Backend frameworks on Easel
Deploy Hono, Express, Fastify, H3, Koa, Elysia, and NestJS servers to Easel as a single function.
Easel deploys a Node.js server built with Hono, Express, Fastify, H3, Koa, Elysia, or NestJS as one Easel Function that handles every request. You keep your app's own routing. Easel finds the app's entry file, bundles it with its imports, and routes all paths to it.
At a glance
| Rendering | Server (every request runs your app) |
| Server runtime | Node.js |
| Adapter required | No. Export the app from its entry file |
| Automatic detection | Yes, from the entry file's import |
| Entry file | app, index, or server at the top level or in src/ (main for NestJS) |
Deploy a backend app
Put the app in an entry file and export it. Easel looks for, in the root directory:
app,index, orserver, with a.js,.cjs,.mjs,.ts,.cts, or.mtsextension, at the top level or insrc/mainwith the same extensions, at the top level or insrc/, for NestJS
CommonJS apps export it with module.exports = app. Then
create a project from your Git
repository or deploy with the CLI:
Easel detects the framework from the entry file importing it, and sets the project's Framework preset. A project created without a preset gets one on its first build. See framework detection.
What Easel deploys
| App output | Easel resource |
|---|---|
| Entry file and its imports | One function that serves every path |
Files in public/ | CDN assets, served before the function |
Routing
Your app's router handles every path, with two exceptions that take precedence over it:
- A root
api/folder. Each file inapi/becomes its own function at/api/<name>. Those routes shadow your app's own/api/*routes. Keep the app's routes insrc/and don't add a rootapi/folder unless you mean to. public/index.html. Files inpublic/are served from the CDN first, sopublic/index.htmlanswers/instead of your app. Remove it, or serve the page from a route.
ES modules
With "type": "module" in package.json, Node.js resolves relative imports
only with their file extension. Write .js even when the source file is
TypeScript:
An import without the extension builds, then fails at runtime with
ERR_MODULE_NOT_FOUND.
Troubleshooting
The build failed with "the build produced no functions"
Easel stopped the build because publishing it would have served your server code as static files. Either:
- The Framework preset is Other while the source is a backend app. Set the preset to your framework in Project settings → Build and redeploy.
- The preset names a backend framework but no entry file matched. Rename or move the app's entry file to one of the entry file names.
/api/* routes return the wrong response
A root api/ folder shadows them. See Routing.
/ shows a static page instead of the app
public/index.html answers /. See Routing.
Known limitations
The app runs as a function, so it doesn't keep in-memory state or open connections between requests. See Functions runtime for what persists, and Limits for durations and sizes.