Executing a node server with Effect

Inside the entry file at main.ts we collect all the layers and execute them in a nodejs server (node:http).

We compose the main app layer from HttpApiBuilder.api, providing all the required dependencies:

const MainApiLive = HttpApiBuilder.api(MainApi).pipe(
  Layer.provide(PaddleApiLive)
);

It's recommended to provide all the dependencies at the service level, so that the final main only contains the core Http layers:

  • dependencies when using Effect.Service
  • Layer.provide when using Context.Tag

The server is based on HttpApiBuilder.serve, providing a NodeHttpServer layer that creates the server using node:http on port 3000:

const HttpLive = HttpApiBuilder.serve(HttpMiddleware.logger).pipe(
  Layer.provide(HttpApiBuilder.middlewareCors()),
  Layer.provide(MainApiLive),
  HttpServer.withLogAddress,
  Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 }))
);

main.ts is then executed using NodeRuntime to start the server:

Layer.launch(HttpLive).pipe(NodeRuntime.runMain);

At the top of the file we also import dotenv/config to load the environment variables from .env file.

The final result is as follows:

import "dotenv/config";

import { MainApi } from "@app/api-client";
import { HttpApiBuilder, HttpMiddleware, HttpServer } from "@effect/platform";
import { NodeHttpServer, NodeRuntime } from "@effect/platform-node";
import { Layer } from "effect";
import { createServer } from "node:http";
import { PaddleApiLive } from "./paddle-api";

const MainApiLive = HttpApiBuilder.api(MainApi).pipe(
  Layer.provide(PaddleApiLive)
);

const HttpLive = HttpApiBuilder.serve(HttpMiddleware.logger).pipe(
  Layer.provide(HttpApiBuilder.middlewareCors()),
  Layer.provide(MainApiLive),
  HttpServer.withLogAddress,
  Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 }))
);

Layer.launch(HttpLive).pipe(NodeRuntime.runMain);

Now executing pnpm run dev will use tsx to execute main.ts and start the server.

package.json
"scripts": {
  "dev": "tsx watch src/main.ts",
  "typecheck": "tsc"
}
pnpm run dev