Cell API
    Preparing search index...

    Cell API

    English | 简体中文

    Cell logo

    Cell

    The TypeScript framework that builds once and runs anywhere, designed for humans and coding agents alike.

    License npm version npm downloads CI Gitee stars GitCode stars

    Quick Start · Deploy Anywhere · Coding Agents · AI · Examples · CLI Reference


    Cell is a serverless-first, component-based, platform-independent application framework for TypeScript. You write plain classes with dependency injection; Cell turns them into a full-stack application, bundles the backend into a single file, and ships the same code to a Node.js server, a container, a single executable, Cloudflare Workers, AWS Lambda, Alibaba Cloud Function Compute, Tencent Cloud SCF or Vercel.

    Cell 4 rebuilds the toolchain on Vite 8 and treats coding agents as first-class users: every command speaks JSON, every error carries a code and a fix, and every project ships with an AGENTS.md and an MCP server.

    One codebase, every runtime Pick a preset at build time: node, cli, cloudflare, fc, scf, lambda, vercel. No platform SDK in your code, no rewrite when you move.
    Single-file output The backend is one dependency-inlined index.mjs. Add --single to embed the frontend as well, or --compile for a standalone executable (Bun, Deno or Node.js SEA).
    Agent-first toolchain --json on every command, structured CellError codes with hints, cell check for types and DI wiring, version-matched docs, and MCP tools for both the project and the running dev server.
    Enterprise-grade architecture Dependency injection and AOP (@Component, @Autowired, @Value, @Aspect), MVC, RPC, declarative transactions, security, JWT and OAuth2.
    Full stack in one process Backend MVC plus React, served on one port in development with frontend HMR and backend hot reload.
    AI native Provider-neutral chat models, prompts and streaming; agents and pi coding agent sessions whose tools are your own services.
    Zero configuration Sensible defaults everywhere. Override only what you need in cell.yml, cell.config.ts or CELL_BACKEND__* environment variables.
    Minimal footprint The toolchain depends on little more than Vite; cloud deployers sign their own requests instead of pulling in vendor SDKs.

    Requires Node.js ^20.19.0 || >=22.12.0.

    npx @celljs/cli init backend my-app     # or: fullstack (React + backend over RPC)
    cd my-app
    npm install
    npx cell dev # http://127.0.0.1:3000, hot reload on save

    A complete backend is a configuration file and a class:

    # cell.yml
    backend:
    cell:
    greeting: Hello from my-app
    // src/node/home-controller.ts
    import { Value } from '@celljs/core';
    import { Controller, Get, Text } from '@celljs/mvc/lib/node';

    @Controller()
    export class HomeController {
    @Value('cell.greeting')
    protected readonly greeting: string;

    @Get()
    @Text()
    home(): string {
    return this.greeting;
    }
    }

    Test it in-process, without opening a port:

    import { createTestApp } from '@celljs/cli';

    const app = await createTestApp({ root: process.cwd() });
    const res = await app.fetch('/'); // 200 "Hello from my-app"
    await app.close();

    The everyday commands:

    Command What it does
    cell dev One port for frontend and backend; HMR for the UI, hot reload for the server, automatic restart on config changes
    cell build Production build into .cell/output (--single, --compile, --preset <name>)
    cell preview Run the build output exactly as the target platform would
    cell deploy Build and publish with the preset's deployer; --dry-run prints the plan
    cell check Configuration, TypeScript types, decorator settings and DI bindings in one pass
    cell info Everything Cell resolved: preset, modes, components, DI modules, hooks, output state
    cell config get <key> --why The merged value of a setting and every file or variable that set it

    Your code stays the same; the preset decides the shape of the output and how it is deployed.

    Preset Output Deploy
    node (default) Node.js HTTP server, one index.mjs Anywhere Node.js runs: VM, container, PaaS
    cli Command-line program on Cell DI Distribute as a file or an executable
    cloudflare Worker + static assets + wrangler.json cell deploy --preset cloudflare
    fc Alibaba Cloud Function Compute (custom runtime) cell deploy --preset fc
    scf Tencent Cloud SCF web function cell deploy --preset scf
    lambda AWS Lambda (Function URL / API Gateway) cell deploy --preset lambda
    vercel Vercel Build Output API (.vercel/output) cell deploy --preset vercel
    cell build --single                      # the whole full-stack app in one file: node index.mjs
    cell build --compile # a standalone executable, no Node.js required on the host
    cell deploy --preset cloudflare --dry-run

    Cell assumes the next developer on your project may be an AI agent, and makes the framework something an agent can use correctly on the first try (design principles).

    • Machine-readable everything: --json on every command returns exactly one JSON result; errors are CellErrors with a stable code, a location and a hint.
    • Context, not guesswork: cell init writes AGENTS.md, a Cell skill and .mcp.json; cell agent sync keeps them matched to the installed versions; cell docs <query> searches the docs shipped with your exact dependencies.
    • MCP built in: cell mcp exposes info, check, config_get, docs_search, build and deploy_plan; cell dev serves /_cell/mcp with routes, DI bindings, resolved config, recent requests, logs and errors of the running app.
    • Fast feedback: cell check catches type errors, missing decorator settings and broken DI bindings before anything runs; createTestApp() gives in-process integration tests.
    // .mcp.json (Claude Code, Cursor, CodeBuddy, ...)
    { "mcpServers": { "cell": { "command": "npx", "args": ["cell", "mcp"] } } }
    import { Component, Autowired } from '@celljs/core';
    import { ChatModel, ProxyChatModel, PromptTemplate } from '@celljs/ai-core';

    @Component()
    export class Assistant {
    @Autowired(ProxyChatModel)
    protected chatModel: ChatModel;

    @Autowired(PromptTemplate)
    protected promptTemplate: PromptTemplate;

    async ask(question: string): Promise<string> {
    const prompt = await this.promptTemplate.create('Answer briefly: {question}', {
    variables: { question },
    // pi:<provider>/<model id>, routed by ProxyChatModel to @celljs/ai-pi
    chatOptions: { model: 'pi:anthropic/claude-sonnet-4-5' }
    });
    const response = await this.chatModel.call(prompt);
    return response.result.output.content;
    }
    }
    • Models: @celljs/ai-pi connects 20+ providers (Anthropic, OpenAI, Google, DeepSeek, Ollama and other OpenAI-compatible endpoints) behind the @celljs/ai-core ChatModel API (pi:<provider>/<model>).
    • Agents: @celljs/ai-agent builds tool-using agents whose tools are ordinary Cell components; events stream over SSE.
    • Coding agents: @celljs/ai-coding-agent hosts pi coding agent sessions inside your application, managed by DI.
    • Terminal UIs: @celljs/tui turns an agent into an interactive command-line chat (see examples/tui-app).
    Dependency injection
    import { Component, Autowired, Value } from '@celljs/core';

    @Component()
    export class A {}

    @Component()
    export class B {
    @Autowired()
    protected a: A; // class injection
    }

    @Component()
    export class C {
    @Value('foo') // configuration injection: 'obj.xxx', 'arr[1]', ...
    protected foo: string;
    }
    Database access with declarative transactions
    import { Controller, Get, Param, Delete, Put, Post, Body } from '@celljs/mvc/lib/node';
    import { Transactional, OrmContext } from '@celljs/typeorm/lib/node';
    import { User } from './entity';

    @Controller('users')
    export class UserController {

    @Get()
    @Transactional({ readOnly: true })
    list(): Promise<User[]> {
    return OrmContext.getRepository(User).find();
    }

    @Get(':id')
    @Transactional({ readOnly: true })
    get(@Param('id') id: number): Promise<User | null> {
    return OrmContext.getRepository(User).findOneBy({ id });
    }

    @Post()
    @Transactional()
    create(@Body() user: User): Promise<User> {
    return OrmContext.getRepository(User).save(user);
    }

    @Put()
    @Transactional()
    async modify(@Body() user: User): Promise<void> {
    await OrmContext.getRepository(User).update(user.id, user);
    }

    @Delete(':id')
    @Transactional()
    async remove(@Param('id') id: number): Promise<void> {
    await OrmContext.getRepository(User).delete(id);
    }
    }
    RPC between frontend, backend and services
    // Shared contract
    export const UserService = 'UserService';
    export interface UserService {
    hello(name: string): Promise<string>;
    }

    // Provider
    import { Rpc } from '@celljs/rpc';

    @Rpc(UserService)
    export class UserServiceImpl implements UserService {
    async hello(name: string): Promise<string> {
    return `Hello, ${name}`;
    }
    }

    // Consumer: a typed remote proxy is injected
    import { Component } from '@celljs/core';
    import { Autorpc } from '@celljs/rpc';

    @Component()
    export class Greeter {
    @Autorpc(UserService)
    protected userService: UserService;
    }

    Runnable applications live in examples/: backend-app, sample-app (React), security-app, jwt-app, schedule, prisma-app, docker-app, standalone-app, mycli, tui-app and coding-agent-app.

    All packages are published under the @celljs scope as dual CommonJS / ES module builds.

    Area Packages
    Core (packages/) core, logger, web, mvc, http, express-adapter, serve-static, rpc, typeorm, cache, retry, schedule, security, jwt, oauth2-core, oauth2-client, oauth2-jose
    Cloud (cloud-packages/) cloud, faas-adapter, lambda-adapter, fc-adapter, scf-adapter, vercel-adapter, oss, cos
    AI (ai-packages/) ai-core, ai-pi, ai-agent, ai-coding-agent
    UI (ui-packages/) react, widget, tui
    Toolchain (dev-packages/) cli, vite, kit

    Issues and pull requests are welcome. The repository is a Bun workspace monorepo built with Turborepo and TypeScript 7.

    Prerequisites: Bun (version pinned in package.json → packageManager) and Node.js ^20.19.0 || >=22.12.0.

    bun install                                   # install dependencies and sync tsconfig references
    bun run build # build all packages
    bun run test # run all tests
    bunx turbo run test --filter=@celljs/core # test one package
    bun run lint # Biome (bun run format to fix)
    bun changeset # describe your change for the next release

    Repobeats analytics

    MIT