Skip to content
Dashboard
Create 6 min read

Frontend Apps

Deploy a server-rendered Node.js frontend with its own public runtime and automatic listener discovery.

Frontend Apps#

Choose Frontend App for a public UI that must run a Node.js server after the build. It is the correct service for Next.js server rendering, Nuxt server output, Remix, SvelteKit with server adapters, and similar frontend frameworks that cannot be deployed as plain static files.

A Frontend App is not a generic backend with a UI attached — it is a dedicated public runtime whose job is to serve the user interface. Use a Web Service when the service’s primary job is a public API or full-stack backend.

When to use — and when not to#

Use Frontend App when:

  • Your Next.js project uses server rendering, API routes, server components that fetch data at request time, middleware, next/image optimization, or any feature that requires a running server.
  • You ship Nuxt with server output, Remix, SvelteKit with adapter-node, Astro with SSR, or another Node-based frontend framework that starts a server via npm run start.
  • You want a separate hostname for the UI distinct from your API’s hostname.

Do not use Frontend App when:

  • The output is a folder of pre-built HTML/CSS/JS (for example dist, out, or build) that can be served as files with no server — ship it as a Static Site instead.
  • The service is primarily an API or background processor that never renders a UI — use a Web Service, Background Worker, or Private Service.
Info

If a build can go both ways (many Next.js projects can export statically *or* run as a server), the deciding factor is whether any page, route, or feature needs runtime execution. If even one does, choose Frontend App.

How it differs from a Static Site#

A Static Site publishes generated files such as dist, out, or build; no application server is started. A Frontend App builds your project, then supervises its production start command for the lifetime of the release. The runtime discovers its reachable TCP listener before the release is marked ready.

ModelWhat runs after the buildWhat is checked
Static SiteThe output directory is uploaded and served as files.No process is started; no runtime readiness is needed.
Frontend Appnpm run start (or equivalent) starts a Node server.NexHost verifies a reachable TCP listener and assigns ingress automatically.

If your Next.js project uses output: "export", it produces static files and can be a Static Site. If it uses API routes, server components that need runtime data, middleware, image optimization, or other server features, choose Frontend App. Uploading a normal .next directory to a Static Site is not supported — .next needs a running server.

Before you begin#

  • The project builds locally with npm run build.
  • The production start script is present and launches a persistent server — for Next.js that is typically next start, usually via npm run start.
  • The application can read PORT from the environment and bind to 0.0.0.0.

Configure a Node frontend#

For a typical Next.js project, the dashboard proposes:

text
Build command: npm run build
Start command: npm run start

Verify each setting rather than accepting blindly:

  1. Build command — must be the same command you run locally to produce the server build. Use the project’s package manager; do not shell out to a different toolchain in the dashboard unless you have tested it.
  2. Start command — must keep a process alive. next start -p $PORT is common for Next.js; other frameworks use npm run start or a small wrapper script. Do not use npm run build as the start command; the runtime needs a long-running server after the build completes.
  3. Framework stack selection — review the detected stack. If the dashboard’s suggestion does not match your framework or monorepo layout, adjust the root directory and commands before deploying.
  4. Environment variables — add runtime values (for example database URLs, API origins) with the appropriate scope. A value the build inlines client-side needs to be present at build time.

Ensure the application’s start script accepts the runtime port. For example, a Next.js script can be written as next start -p $PORT, or more explicitly in package.json:

json
{ "scripts": { "build": "next build", "start": "next start -p $PORT" } }

NexHost supplies PORT=3000 as a compatibility default and automatically discovers the listener your application actually opens. A normal internal port such as 3000 is safe because every deployment is isolated in its own Docker network namespace.

Warning

Avoid "build in one command" patterns like npm run build && npm run start in the start command. Keep build and start separate: the build phase runs once, then the start command is supervised for the lifetime of the deployment.

TCP readiness#

NexHost does not require a health URL or user-selected port. It waits for the frontend to open a listener on 0.0.0.0, discovers that port, and creates the public route. If startup readiness times out, inspect the start command, build log, and server binding first; a successful build followed by a readiness failure is a startup/configuration issue, not a source issue.

Deploy#

  1. In New Project, choose Frontend App.
  2. Connect a supported source — a repository, archive, or folder. Confirm the branch and root directory.
  3. Review the build and start commands and output expectations.
  4. Deploy. On success, the generated public URL and deployment detail page are shown after the release becomes ready.

After the first successful release you can add a custom hostname: Custom Domains works for every public runtime, including frontend apps.

Troubleshooting#

SymptomWhat to check
Build succeeds, startup readiness times outIs the start command a persistent server? Does it bind to 0.0.0.0 and reach its listen call after initialization?
output: "export" hint in logs, or static-output warningsA static-style Next build was uploaded. If the app needs server features, choose Frontend App and ship the source, not the .next or out directory.
Start script "not found"Verify the package manager, root directory, and that the workspace has a package.json at the chosen path.

See Deployment Troubleshooting for the full symptom table and Logs for how to read each deployment stage.

Common mistakes#

  • Reusing npm run build where a long-lived start command belongs.
  • Uploading the .next directory and pointing a Static Site at it — use a Frontend App instead.
  • Binding the server only to 127.0.0.1, which makes it unreachable from the runtime network.