Effect Start Framework
effect-start is a framework for building declarative full-stack applications by deeply integrating with the Effect ecosystem. Currently at version 0.36.0, the project is in its early stages of development, implying a rapid release cadence with potential for frequent, significant updates. It offers features such as automatic file-based routing, supporting frontend pages, backend API endpoints, and composable Route Layers for middleware. A key architectural design is a unified `server.ts` entrypoint for both development and production environments, aiming to eliminate configuration divergence. The framework also includes a lightweight Tailwind CSS plugin with minimal configuration, primarily demonstrated within the Bun runtime environment. Its declarative approach and reliance on Effect distinguish it from more imperative or traditional full-stack solutions, catering to developers already familiar with or interested in the Effect paradigm.
Common errors
-
Error: Cannot find module 'effect-start/tailwind'
cause The Tailwind CSS plugin path in `bunfig.toml` is incorrect, or `effect-start` is not correctly installed, or Bun cannot resolve the path.fixEnsure `effect-start` is installed (`bun add effect-start`) and that `bunfig.toml` has `plugins = ["effect-start/tailwind"]` under `[serve.static]` exactly as specified in the documentation. -
TypeError: Cannot read properties of undefined (reading 'layer') at Start.serve
cause The function passed to `Start.serve()` is not correctly returning a Layer, or the `server.ts` file's default export is not a valid Effect Layer.fixVerify that your `server.ts` file exports a default `Start.layer(...)` composition, and that `Start.serve(() => import("./server.ts"))` correctly imports and executes this. Ensure all inner layers are also correctly constructed. -
Error: Failed to load module specifier './routes/routes.gen.ts'
cause The file-based router is configured to load `routes.gen.ts`, but this file does not exist or cannot be resolved at runtime. This file is typically generated by a build step or dev server process.fixEnsure your development server or build process is running and successfully generating `src/routes/routes.gen.ts`. Check the console for any errors during the route generation phase.
Warnings
- breaking The project is explicitly stated as 'early stage' (v0.36.0), indicating that APIs are subject to significant change, and breaking changes are highly probable across minor versions. Users should expect frequent updates and may need to adapt their code.
- gotcha While not explicitly mandated, the documentation and examples heavily feature the Bun runtime (`bun add`, `bunfig.toml`). Users attempting to run `effect-start` with Node.js or Deno may encounter compatibility issues or missing features, particularly with tooling-related aspects like the Tailwind plugin configuration.
- gotcha `effect-start` is built entirely on the Effect ecosystem. Developers new to Effect might face a steep learning curve understanding its declarative, functional, and highly typed patterns (e.g., Layers, Fibers, Streams, Schemas) which are fundamental to `effect-start`'s architecture.
- gotcha `effect-start` is an ES Module (ESM) first framework, evidenced by the use of `import.meta.resolve` and `import.meta.main`. Attempting to use CommonJS `require()` syntax for importing `effect-start` modules will result in `ERR_REQUIRE_ESM` or similar errors.
Install
-
npm install effect-start -
yarn add effect-start -
pnpm add effect-start
Imports
- Start
const Start = require('effect-start')import { Start } from 'effect-start' - FileRouter
import FileRouter from 'effect-start'
import { FileRouter } from 'effect-start' - Start.layer
new Start.Layer()
Start.layer(...)
Quickstart
import { FileRouter, Start } from "effect-start";
// This layer applies configuration and changes the behavior of the server.
// It expects a FileRouter.layer, which automatically loads routes.
export default Start.layer(
FileRouter.layer({
// Specifies how to dynamically load the generated routes file.
// `routes.gen.ts` is typically created by a build step or dev server.
load: () => import("./routes/routes.gen.ts"),
// Provides a path hint for the router, useful for `import.meta.resolve`
path: import.meta.resolve("./routes/routes.gen.ts"),
})
);
// This block ensures the server is only started when the file is run directly
// (e.g., `bun run server.ts`), not when imported as a module.
if (import.meta.main) {
// `Start.serve` takes a function that returns the main application layer,
// typically the default export of this `server.ts` file.
Start.serve(() => import("./server.ts"));
}