Devora.js vs. other frameworks

Where Devora.js stands next to the tools you're probably weighing it against — including where they're ahead. Speed numbers live on Performance.

Devora.js rows: @devorajs/core 0.3.5, checked October 16, 2026Other frameworks: checked October 16, 2026

Choose Devora.js if…

  • you're building several apps (marketing site, dashboard, admin) that should share one backend and one login, and deploy separately;
  • you want render modes, caching and security settings written in the code, not inferred;
  • one session for both browsers (cookie) and mobile clients (Bearer token) saves you a second auth system;
  • you're comfortable on a pre-1.0 framework with a small community.

Choose something else if…

  • you want the largest ecosystem and the most answers online, or have one app: Next.js;
  • you're building a content-heavy site and value satisfaction scores: Astro;
  • you need a mature, full-featured backend today — dependency injection, validation, WebSockets, jobs: NestJS or Fastify;
  • you need WebSockets or background jobs built in, or a long track record right now.

Full-stack and frontend frameworks

Next.js, React Router v8 (framework mode — formerly Remix), SvelteKit and Astro. Each topic below has its own table; pick which frameworks to show, and on a phone each feature becomes a card.

Rendering model

Choose how each route renders

Every route says how it renders, in its own file. Choosing a mode per route is not unique to Devora.js — the table below shows who else does it. The narrow claim here is only that the choice is one explicit line in the route file.

  • ssr

    Stable

    The loader runs on every request and the page is rendered fresh.

    Use it for: Per-user or per-request data, anything behind a login.

    export const renderMode = "ssr";
    Limits

    The default for a route that exports nothing (unless the app sets another default).

    Full explanation

  • ssg

    Stable

    Rendered once during devora build and served as static HTML.

    Use it for: Content that does not change per request: docs, marketing, blog posts.

    export const renderMode = "ssg";
    Limits

    A dynamic route needs getStaticParams(). In dev it renders live per request; it is pre-rendered only by a production build.

    Full explanation

  • csr

    Limited

    The server sends an empty shell; the component mounts in the browser.

    Use it for: Pages that only make sense in a browser, behind your own client data layer.

    export const renderMode = "csr";
    Limits

    The loader never runs, and the page needs the client bundle to show anything. Import from @devorajs/core/client.

    Full explanation

  • isr

    Not verified on serverless

    Like ssg, but regenerated once a revalidate window has passed.

    Use it for: Mostly static content that should refresh on a schedule.

    export const renderMode = "isr"; export const revalidate = { seconds: 3600 };
    Limits

    Reliable under a long-lived Node server. On Vercel/Netlify the function's filesystem is not guaranteed to persist, so ongoing regeneration there has not been verified.

    Full explanation

  • streaming

    Limited

    The shell is sent at once; island content streams in as it resolves.

    Use it for: A page with one slow section you do not want the whole response to wait for.

    export const renderMode = "streaming";
    Limits

    GET only (no action). Delivered as one buffered response on Netlify; not verified on a live deployment elsewhere.

    Full explanation

Who else has it

Show
Render modes: Devora.js compared with full-stack frameworks
FeatureDevora.jsNext.jsReact RouterSvelteKitAstro
Render mode per route
ssrBuilt inrenderMode = "ssr" in the route file.Built inDynamic rendering of a route.Built inssr: true; an app-wide setting.Built inThe default; export const ssr per page.Built inprerender = false per page, or output: 'server'.
ssgBuilt inrenderMode = "ssg" and getStaticParams().Built inPrerendered; generateStaticParams for dynamic routes.Built inprerender() in config lists the URLs.Built inexport const prerender = true per page or layout.Built inThe default; prerender = true per page.
csrBuilt inrenderMode = "csr"; the loader never runs.PartialClient Components, or a single-page-app setup; not a per-route mode.Built inssr: false (SPA mode, app-wide); clientLoader per route.Built inexport const ssr = false per page or layout.Not verifiedClient islands exist; a whole-page client mode was not checked.
isrBuilt inrevalidate = { seconds }; not verified on serverless.Built inexport const revalidate = 60; per-instance cache unless you add a shared handler.Not built inNot described on the pages checked.PartialOnly through adapter-vercel's isr option.PartialOnly through the Vercel adapter's isr option.
streamingBuilt inrenderMode = "streaming"; GET only; buffered on Netlify.Built inSuspense and loading.js.Built inReturn promises from loaders; Await in Suspense.Built inPromises from a server load; buffered where the platform cannot stream.Built inHTML streaming in on-demand rendering.

Checked against each framework's own documentation on October 16, 2026; a cell says "Not verified" where that page was not checked. Sources: Next.js: Incremental Static Regeneration · Next.js: Streaming · React Router: Rendering strategies · React Router: Streaming with Suspense · SvelteKit: Page options · SvelteKit: Loading data (streaming) · SvelteKit: adapter-vercel (ISR) · Astro: On-demand rendering · Astro: Vercel adapter (ISR). Next.js's ssr, ssg and csr cells are read from the two Next.js pages above and the Next.js docs they link to.

Show
Rendering: Devora.js compared with full-stack frameworks
FeatureDevora.jsNext.js 16React Router v8SvelteKit 3Astro 7
Per-route rendering
Render mode chosen per routeBuilt inssr ssg csr isr streaming, one export in the route fileBuilt inStatic by default, dynamic when a route uses request data; revalidate and Suspense per routePartialSSR and SPA mode are app-wide (ssr in config); pre-rendering lists URLsBuilt inprerender, ssr, csr exports per page or layoutBuilt inprerender per page; output sets the default
Catch-all routes ([...slug])Built inPages and API routes; ctx.catchAll.slug is the array (since 0.3.4)Built inBuilt inSplat routes: "*"; the rest is params["*"]Built inRest parameters, [...path]Built inRest parameters, [...path]
Query string and headers in data loadingBuilt inctx.url, ctx.headers, ctx.ipBuilt inBuilt inBuilt inBuilt in
Pre-rendered pages: validators and compressionServed from memory with an ETag (304 on a repeat visit) and brotli/gzip under devora start; 64 MB total, 2 MB per file, checked against the disk once a second

Honest note: explicit render-mode selection isn't unique to Devora.js — SvelteKit and Astro do it per route, and Next.js 16 closed most of the gap. Incremental regeneration is built in on Next.js and only a platform option elsewhere; Devora.js's version is the least battle-tested on serverless hosts.

Multi-app architecture

The reason Devora.js exists. Turborepo and Nx are monorepo task runners rather than frameworks, so a "—" or "Not its job" cell is not a knock against them.

Show
Several apps in one project
FeatureDevora.jsNext.js (Multi-Zones)Turborepo / NxOthers
Several apps in one project
Multiple apps, one repoBuilt inOne devora.config.ts; each app deploys separately, on its own domainPartialSeparately deployed apps served under one domain, routed by rewritesBuilt inThis is their core purposeNot built inNot a first-class concept
Navigating between appsFull page load (separate apps)Hard navigation between zones, soft within oneNot its jobNot a routing toolNot its job
One backend shared by every appBuilt inOne packages/backend by defaultPartialEach zone has its own Route Handlers; share code as a packageNot built inYou wire the backend yourselfNot its job
One login across appsBuilt inEvery shared app accepts the same session; cookie.domain shares the browser login across subdomainsPartialNo sessions built in, but zones share one domain, so a cookie-based auth library carries acrossNot built inYou build it yourselfNot its job
Build caching and task orchestrationNot built inNot Devora.js's jobNot its jobBuilt inTheir real strengthNot its job

Honest note: Turborepo and Nx solve "build this repo full of apps fast"; Devora.js solves "these apps share a backend and a session system out of the box". You could use Turborepo and Devora.js together. Multi-Zones' one-domain model gets browser cookie sharing for free; Devora.js shares the login across subdomains only when shared.sessions.cookie.domain is set.

Sessions and auth

Show
Sessions: Devora.js compared with full-stack frameworks
FeatureDevora.jsNext.js 16React Router v8SvelteKit 3Astro 7
Sessions
Server-side sessions built inBuilt inOpaque IDs in a store you provide, revocableNot built inA cookies API; the docs recommend an auth or session libraryBuilt increateCookieSessionStorage, createSessionStorage, per route in loaders and actionsNot built inCookies in the handle hook; sessions are your code or a libraryBuilt inSessions API since Astro 5.7; needs a storage driver
One session as cookie and Bearer tokenBuilt inOne primitive, revoked on both at onceNot built inNot built inNot built inNot built in
CSRF protection on by defaultBuilt inFor cookie sessions; ctx.verifyCsrf() per actionPartialServer Actions check Origin; allowed origins are configurableNot verifiedPartialOrigin check on form postsPartialOrigin check on form posts

Honest note: built-in sessions aren't unique (React Router, Astro). The narrow claim: one session that works as an HttpOnly cookie and as a Bearer token, revoked on both at once, shared by every app in a project. Checking who someone is stays your code: Devora.js ships no auth provider, and none of the others is a replacement for one either.

Backend frameworks

Express, Fastify and NestJS, compared on what an API needs.

API error handling

Show
API error behavior: Devora.js compared with backend frameworks
FeatureDevora.jsExpress 5Fastify 5NestJS 12
API behavior, defaults only
Uncaught errors become JSONBuilt inReal message hidden in productionNot built inHTML error page, message hidden in productionPartialJSON, but the raw error message is sent even in productionBuilt inJSON, message hidden
Unmatched route is a JSON 404Built inUnder /apiNot built inHTML Cannot GET … pageBuilt inBuilt in
Wrong HTTP method is a 405Built inWhen the route exports methodsNot built in404Not built in404Not built in404

Tested directly in production mode with defaults only (October 16, 2026): Express 5.3.0, Fastify 5.12.7, NestJS 12.1.3 and Devora.js 0.3.5.

Built in, or bring your own

Show
What is built in: Devora.js compared with backend frameworks
FeatureDevora.jsExpress 5Fastify 5NestJS 12
Built in, or bring your own
CORSBuilt incors in app.config.tsUse a librarycors packageUse a libraryOfficial plugin (@fastify/cors)Built inapp.enableCors()
File uploads (multipart)PartialPage forms: File objects in action; API routes parse the body themselvesUse a librarymulterUse a libraryOfficial plugin (@fastify/multipart)Built inFileInterceptor (Multer, in @nestjs/platform-express)
ValidationUse a libraryDocumented Zod patternUse a libraryBuilt inJSON Schema (Ajv) per routeBuilt inValidationPipe (class-validator)
Rate limitingUse a libraryDocumented patternUse a libraryUse a libraryOfficial plugin (@fastify/rate-limit)Use a libraryOfficial module (@nestjs/throttler)
WebSocketsUse a libraryA separate realtime server (Socket.IO) works; ws works through a small wrapper around createNodeServer; server-sent events from an API route do not work yet: Live updates (WebSockets)Use a libraryUse a libraryOfficial plugin (@fastify/websocket)Built inGateways in @nestjs/websockets (socket.io or ws)
Background jobsUse a libraryBullMQ with Redis and a worker, a SQLite queue with a worker, and node-cron were tested on one Node server; not verified on Vercel or Netlify: Background jobsUse a libraryUse a libraryUse a libraryOfficial modules (@nestjs/bullmq, needs Redis; @nestjs/schedule)
Dependency injectionNot built inBy designNot built inNot built inBuilt inCore feature

Each row was checked against the framework's documentation on October 16, 2026. "Use a library" includes the official packages each project maintains.

Honest note: NestJS and Fastify are more complete "batteries included" backend frameworks today. Devora.js's backend is closer to Express's minimalism, with a JSON error contract, method checks and CORS that Express doesn't give you by default. For WebSockets and background jobs it documents tested patterns, not built-ins: Live updates (WebSockets), Background jobs.

Scale, honestly

Devora.js is new and small. npm downloads for one full week, Sep 28, 2026 – Oct 4, 2026:

npm downloads, 2026-09-28 to 2026-10-04
PackageDownloads
express169.5M
next76.9M
react-router68.7M
@nestjs/core19.1M
fastify18.1M
astro7.9M
@sveltejs/kit3.6M
@devorajs/core91
Source: npm's public downloads API (api.npmjs.org), fetched Oct 15, 2026 by scripts/fetch-npm-downloads.mjs. The most recent week with no missing days was used (the week after it is missing a day for every package). react-router counts every React Router user, not only framework mode. All counts include CI runs and transitive installs, which inflate express the most.

Per State of JS 2025 (the most recent edition): Next.js leads meta-framework usage but is losing satisfaction; Astro ranks highest on satisfaction, 39 points ahead of Next.js. On the backend side, Express leads usage with NestJS growing; Hono tops satisfaction (outside this page's scope, but worth knowing). Pick Devora.js for what it does differently, not for maturity.

Known limitations

As of @devorajs/core@0.3.5, checked in its source:

  • An API route's response headers are a plain object, so one response can send only one Set-Cookie; responses are sent in one piece, so there are no server-sent events.
  • No built-in validation or rate limiting. WebSockets and background jobs are not built in either, but both have tested setups: Live updates (WebSockets) and Background jobs. Server-sent events from an API route do not work yet.
  • streaming is GET-only, and on Netlify it arrives as one buffered response.
  • isr regeneration on Vercel/Netlify's serverless filesystem hasn't been verified; it is reliable under a long-lived Node server.
  • Pre-rendered pages and built files are held in memory (64 MB total, 2 MB per file) and checked against the disk once a second; devora start needs a restart for changed route code.
  • Desktop and native mobile apps are planned goals, not started.
  • Pre-1.0: behavior changes can land in any release; the CHANGELOG lists them first.

Build time, requests/second, memory and JavaScript sent, measured against Next.js, Astro, SvelteKit and React Router on the same pages: see Performance.

When to choose which

Next.js

Choose it if you want the largest ecosystem, or one app on the most-used React framework.

Not if several deployed apps should share one backend and one login without wiring it yourself.

Astro

Choose it if you build a content-heavy site with little client JavaScript by default.

Not if you need a shared login and backend across several apps.

NestJS / Fastify

Choose it if you need a mature backend today: DI, validation, WebSockets, jobs.

Not if you also want server-rendered React pages in the same project.

Devora.js

Choose it if several apps should share one backend and one login and deploy separately, and a pre-1.0 framework is fine.

Not if you need the largest ecosystem, a long track record, or built-in WebSockets and jobs.