Introduction
Exis (ExisJS) is a batteries-included backend framework for Node.js. It brings the file-based, convention-over-configuration developer experience of modern frontend meta-frameworks to backend API development: folders and files instead of manual wiring, with the essentials (routing, validation, queues, WebSockets, cron, DI) built in rather than assembled from a dozen separate packages.
Routing is handled by a radix-tree matcher, and the framework supports two ways to define the same routes: Functional (factory functions) and Class-Based / OOP (decorators, in the style of Angular/NestJS). Both compile to the same internal route representation, run through the same middleware pipeline, and can be mixed file-by-file in the same project. Pick whichever fits a given part of your codebase.
Philosophy
Frontend frameworks like Next.js, Remix, and Nuxt improved developer productivity significantly through file-based routing and convention-over-configuration architecture. Good tools exist for Node.js backends too, but assembling them into a coherent application still typically means a lot of manual wiring and architectural boilerplate.
Exis aims to provide that out-of-the-box application architecture for backends: create a folder, get a route; create a gateway.ts, get folder-scoped middleware; import a module, get its providers registered. Job queues, WebSockets, cron scheduling, and schema validation are part of the standard library rather than bring-your-own dependencies. This means a new project starts with a coherent structure instead of a blank index.js and a pile of choices to make first.
Installation
The fastest way to start is the Exis CLI, which scaffolds a new project directory with the core files and a conventional base structure already in place. This is the recommended path for first-time users.
The CLI walks you through initial project setup (TypeScript config, import aliases, and package manager selection: it detects npm, yarn, pnpm, or bun automatically). See Installation for the full list of prompts and options.
Quick Start
Both paradigms are shown throughout these docs side by side. Pick whichever you're using, or mix them across your project.
Functional API
import { controller, route } from 'exisjs/router'
export default controller({ getUsers: route.get('/', { handle(req) { // Return a realistic response structure return { data: [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ], total: 2 } }, }),})Class-Based (OOP) API
import { Controller, Get, Req } from 'exisjs/decorators'import type { Request } from 'exisjs'
@Controller()export default class UsersController { @Get('/') getUsers(@Req() req: Request) { // Return a realistic response structure return { data: [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ], total: 2 } }}Save this as src/http/users/route.ts, run exis dev, and GET /users will return your mocked users list.
Adding to an existing project
You can also add Exis to an existing Node.js project instead of scaffolding a new one:
In this case you'll set up the project structure yourself: an exis.config.ts at the project root and a src/http directory for your routes. See Structure for the conventions the framework expects.
What's next
- Installation: CLI setup and project scaffolding in detail.
- Structure: the folder conventions Exis expects and why.
- Routing: how file-based routing, dynamic segments, and gateways work together.