Compared to plain Next.js
See what changes when your Next.js App Router code runs on Stardeck: the runtime, the data layer, auth, deploys and who keeps the app current.
A Stardeck app is stock Next.js: App Router, React Server Components,
page.tsx, route.ts, layout.tsx, Tailwind. Nothing proprietary replaces the
framework, and your React is portable.
What differs is where requests are decided, where data lives, who holds credentials and who keeps the app current.
At a glance
| On your own Next.js app | On Graviton | Why |
|---|---|---|
Choose a host and run deploy | Merge a pull request into main, then publish | Standard size builds to a Cloudflare Worker; Large builds a Node.js server with more memory |
| Pick a runtime per route | Worker runtime at Standard size | No Node.js runtime at Standard, which is also why middleware.ts must not be renamed to proxy.ts |
| Provision Postgres, pick an ORM, own migrations | Data Store + data-store-sdk (Kysely) | Schema changes are platform operations or Module ledger entries; the driver is HTTP, so no interactive transactions |
| Add NextAuth, Clerk, or roll your own | project-auth | Sign-in, RBAC, SSO and admin/user dashboards ship with it; visibility is enforced at the edge |
| Guard routes in middleware | Guard in the layout and in each API handler | Host classification, tenant lookup and public/internal gating happen before your code; API paths are never edge-gated |
vercel cron or a cron container | scheduling-sdk | The platform calls your deployment on a schedule |
| Wire Stripe, an email provider, an S3 bucket | payments-sdk, email-sdk, storage-type Data Store | The platform holds credentials; every call is HMAC-signed by the SDK |
| Rely on ISR and the data cache | Treat rendering as per-request; cache deliberately | No incremental cache at Standard size. See Constraints |
Edit next.config.ts freely | Ask Stardeck for config changes | Updates edit that file |
| One project per audience: site, admin, POS | Surfaces in one repo | Each gets its own hostname, icon and install identity from one deploy |
| Own your dependency and framework upgrades | Updates move the app forward | Each released version is merged into your repo like any Git merge |
.env.local you maintain | npm run env:pull from the platform | Secrets are stored and decrypted by the platform, per environment |
Webhooks to localhost via a tunnel | Exercise inbound traffic in the sandbox | Nothing inbound is routed to a local dev server, by design |
What this buys and what it costs
flowchart TB
subgraph Y["What you stop owning"]
Y1["Infrastructure and credentials"]
Y2["Auth, RBAC and the sign-in surface"]
Y3["Framework and dependency upgrades"]
Y4["Hostnames, TLS and PWA identity per audience"]
end
subgraph C["What you accept"]
C1["Worker limits at Standard size, including a 10 MiB bundle"]
C2["No interactive database transactions"]
C3["Some files and operations are platform-owned"]
C4["Deploys go through the platform, not your CI"]
end
Y --> V["One codebase, many audiences,<br/>that keeps moving forward"]
C --> V
Each constraint is enforced by something you can see: a lint rule, a build failure or a file header.
Updates
New apps start from a shared foundation and don't run platform migrations.
When Stardeck releases a new version, the app shows Update available and you
merge it, in-product or locally. The update brings new SDK
versions, config changes and a new AGENTS.md.
- Stay on the SDK surface. Code that uses an SDK's documented API survives updates. Code that reaches around it (hand-built platform requests, copies of generated files) is what conflicts or breaks.
- Don't edit
AGENTS.md. The app keeps Stardeck's copy, and updates change it. Put project conventions in a separate file.
Still Next.js
Things that work exactly as you expect, with no Stardeck-specific wrapper: the App
Router and route groups, Server Components and Server Actions, layout.tsx
composition, streaming, next/image (against configured hosts), Tailwind,
react-hook-form, TanStack Query, Zod, Playwright and Vitest.
If a Next.js pattern is not listed on the Constraints page as restricted, assume it works.