Skip to content

Repository files navigation

VextJS

npm version License: Apache-2.0 Node.js TypeScript Docs

Ship APIs and server-rendered React pages from one Node.js application.

VextJS is a full-stack Node.js application framework built around one route model and request lifecycle. Routes, services, validation, security, OpenAPI, typed contracts, and React SSR evolve together without introducing a second routing system.

The npm package name is vextjs; the CLI binary is vext. Requires Node.js >=20.19.0. Cold-start from the registry with npx vextjs …. After install, use project scripts or local npx vext.

Docs: https://devcodex-labs.github.io/vextjs/ · Migration: MIGRATION.md · Changelog: CHANGELOG.md


One route model Contracts stay connected Start with only what you need
JSON and HTML use src/routes/**, shared services, and the same security chain. Route contracts drive validation, OpenAPI, interactive docs, and generated client types. The default starter is full-stack; API-only remains a first-class template.

Get started

# Package name is vextjs — runs the published `vext` binary from this package.
npx vextjs create my-app
cd my-app
npm run dev

Default scaffold: TypeScript + fullstack React + native adapter.

# API-only
npx vextjs create my-api --template api --frontend none

# Other adapters / JS
npx vextjs create my-app --adapter hono
npx vextjs create my-app --js

Open http://localhost:3000/ and, with OpenAPI enabled, http://localhost:3000/docs.

The package is vextjs; its installed CLI binary is vext. Use npx vextjs create before installation, then project scripts or local npx vext.


Why VextJS

When the application grows VextJS keeps Practical result
An API also needs server-rendered pages URL ownership in src/routes/** No second route or data-loading language
Validation, docs, and clients start to drift Contracts beside the handler OpenAPI, live docs, and typed clients share one source
Authentication, sessions, cache, and errors multiply One request lifecycle JSON, HTML, and page navigation cross the same policies
Tooling becomes a project of its own CLI, esbuild frontend delivery, testing, and production start A shorter path from scaffold to deployable Node service

One route model

The default starter demonstrates the same service feeding a server-rendered page and a documented API route:

import { defineRoutes } from "vextjs";

export default defineRoutes((app) => {
  app.get("/", {}, async (_req, res) => {
    const greeting = await app.services.example.greeting("Vext");
    res.render("index", { greeting, renderedAt: new Date().toISOString() });
  });

  app.get(
    "/api/hello",
    {
      docs: { summary: "Get the starter greeting" },
    },
    async (_req, res) => {
      res.json(await app.services.example.greeting("Vext"));
    },
  );
});

Routes remain the URL authority. Services own reusable business work. res.json() and res.render() choose the representation without bypassing middleware, validation, auth, cache, redirects, or error handling.


What you get

Runtime

  • Convention routing — file path under src/routes/** → URL prefix; (path, options, handler) API
  • Plugins & services — topological plugin load; src/services/**app.services
  • Validation & route contractsschema-dsl, response schemas, OpenAPI, and generated client types
  • OpenAPI + Docs Renderer/openapi.json and interactive first-party /docs
  • Database lifecycle — setting config.database activates built-in MonSQLize connections, model loading, and cleanup
  • Route cachecache: 60 / tags / Vary
  • Session, cookies, CSRF, auth, security headers — first-party contracts
  • Production lifecycle — graceful shutdown, cluster workers, heartbeats, and rolling restart
  • Startup lifecycle — bootstrap configuration providers and src/preload/** process-early hooks

Full-stack UI (same routes)

  • React SSR / hydration via res.render()
  • Same-route client navigation — browser navigation reuses the existing server route lifecycle
  • Static / revalidate freshness and local image/font pipeline
  • Typed API client generation (dist/client/api.generated.ts when frontend build + apiClient are enabled)
  • Vext JSCSS (vextjs/style) and esbuild-powered frontend delivery — one toolchain

DX

  • CLI — create, dev, build, start, typegen, doctor
  • Three-tier hot reload — route hot swap, service/model structural reload, and safe cold restart
  • React Fast Refresh — frontend updates without restarting the backend runtime
  • TestingcreateTestApp from vextjs/testing without binding a real HTTP port

Simplified project model

my-app/
├── src/
│   ├── config/          # default + env profiles + optional bootstrap
│   ├── routes/          # HTTP routes (URL authority)
│   ├── services/        # → app.services.*
│   ├── models/          # optional database models
│   ├── plugins/
│   ├── middlewares/
│   ├── frontend/        # pages, components, styles, assets
│   ├── preload/         # process-level early scripts
│   └── locales/
├── package.json
└── tsconfig.json

Good fit

VextJS is a strong fit when:

  • a Node API needs server-rendered product, admin, or internal pages without splitting ownership;
  • one team wants routes, services, validation, auth, cache, docs, and clients to evolve together;
  • API-only today may become full-stack later, or a full-stack app still needs a first-class API;
  • production remains a Node service and an esbuild-based frontend toolchain is enough.

Boundaries

VextJS uses route-native SSR: src/routes/** + res.render() provide SSR, hydration, Suspense, opt-in Streaming SSR, same-route navigation, static/revalidate freshness, and local media. It intentionally does not implement React Server Components, Server Functions or Actions, partial prerendering (PPR), or third-party bundler plugin ecosystems. Those models would introduce a second execution or routing authority and weaken the framework's single-route contract.

Read the exact lifecycle, trade-offs, and exclusions in Frontend boundaries and roadmap. Implementation guides cover rendering modes, data flow, assets and media, and the typed API client.


HTTP adapters

Pick the stack that fits your deployment; business routes stay the same.

Adapter Extra packages Notes
native (default) none Node HTTP + route-core; no extra HTTP framework package
express express Use when you need that middleware ecosystem
fastify fastify Use when you need that plugin ecosystem
koa koa Use when you need that middleware style
hono hono, @hono/node-server Node.js adapter with Web Standard APIs; not an Edge runtime adapter
// src/config/default.js
export default {
  adapter: "native", // or "fastify" | "hono" | "express" | "koa"
};

Benchmark methodology and numbers: Benchmark docs · reproduce with npm run test:bench in this repo.


CLI

Invoke via npx vextjs <cmd> (package) or, inside a project, npx vext <cmd> / npm scripts.

Command Purpose
vext create <name> Scaffold (default fullstack-react)
vext dev Dev server + hot reload + typegen preflight
vext build Compile server (+ frontend when enabled)
vext start Run production / built output
vext typegen Generate app.services / app.extend types
vext doctor routes Static route diagnostics (experimental)
npx vextjs create my-app
cd my-app
npm run dev          # → vext dev
npm run build        # → vext build
npm start            # → vext start

Dev reload: T1/T2 soft reload (ms), T3 cold restart (config/plugins/env). Keys: r restart, h soft reload, c clear, ? help.


Configuration

built-in defaults → default → {profile} → local → bootstrap providers → CLI overrides

Select profile with vext start --config <name> or VEXT_CONFIG=<name> (do not rely on baked process.env.NODE_ENV after vext build for profile selection).

Common fields: port, host, adapter, logger, cors, bodyParser, rateLimit, openapi, frontend, cache, session, shutdown. See the configuration guide and configuration reference before changing production behavior.


Testing

import { describe, it, expect } from "vitest";
import { createTestApp } from "vextjs/testing";

describe("API", () => {
  it("responds", async () => {
    const app = await createTestApp({ rootDir: "/path/to/project" });
    const res = await app.request.get("/");
    expect(res.status).toBe(200);
  });
});

Documentation and AI assistants

Resource URL
Human docs (EN/ZH) https://devcodex-labs.github.io/vextjs/
Quick start https://devcodex-labs.github.io/vextjs/guide/quick-start
Frontend guide and typed client https://devcodex-labs.github.io/vextjs/frontend/getting-started
Runtime boundaries https://devcodex-labs.github.io/vextjs/frontend/boundaries-and-roadmap
llms.txt https://devcodex-labs.github.io/vextjs/llms.txt
capabilities.json https://devcodex-labs.github.io/vextjs/capabilities.json
docs-manifest.json https://devcodex-labs.github.io/vextjs/docs-manifest.json

For AI assistants: prefer citing docs-manifest.json canonical URLs; check capabilities.json and the boundaries page before describing frontend capabilities. Do not invent features from React version, SSR, or Suspense alone.

Chinese documentation: site locale /zh (this package ships one English README entry).


Migration

Schema-dsl v3 / monsqlize / frontend contracts: MIGRATION.md.


Contributing

See the contributing guide.

git clone https://github.com/devcodex-labs/vextjs.git
cd vextjs
npm ci
npm test
npm run build

License

Apache-2.0 © DevCodex Labs · github.com/devcodex-labs/vextjs

About

VextJS is a high-performance Node.js framework for maintainable backend and full-stack services.

Topics

Resources

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages