Supported Frameworks

Temps auto-detects many frameworks by inspecting files in your repository and applies the appropriate build configuration. Some — notably PHP and Ruby — are supported but not auto-detected, and need a preset chosen on the project. This page lists what is detected, what you select yourself, and the build behaviour to expect from each.


How framework detection works

Temps uses two distinct mechanisms, and it helps to know which one you're relying on.

1. Preset detection (repository files). When you connect a repository, Temps scans each directory for known filenames and reports every preset that matches, so you can pick when more than one applies — a repo with both a Dockerfile and a next.config.ts offers you both. Matches are ordered by priority:

  1. Docker Compose — a recognised compose file
  2. Dockerfile
  3. Framework config filesdocusaurus.config.js/.ts, next.config.js/.mjs/.ts, vite.config.js/.ts, rsbuild.config.ts, or a react-scripts entry inside package.json
  4. Language manifestsCargo.toml, go.mod, requirements.txt/pyproject.toml/setup.py/Pipfile, pom.xml/build.gradle/build.gradle.kts
  5. Nixpacks — only when an explicit nixpacks.toml is present

If nothing matches, the build fails with Could not auto-detect project type from files… Please specify a preset explicitly — there is no silent fallback. You then pick a preset yourself. The full selectable set is:

nextjs, vite, react-app, rsbuild, docusaurus, rust, go, python, java, docker-compose, dockerfile, custom, and nixpacks plus its per-language variants nixpacks-node, nixpacks-python, nixpacks-rust, nixpacks-go, nixpacks-java, nixpacks-php, nixpacks-ruby, nixpacks-deno, nixpacks-elixir, nixpacks-csharp, nixpacks-dart and nixpacks-static.

There is no dedicated preset for Astro, Nuxt, Remix, Vue, NestJS, SvelteKit, Angular, Rails or Laravel. Those frameworks deploy through one of the presets above — usually vite (SvelteKit builds on Vite), python, or a nixpacks-* language variant — with the start command tuned by the dependency detection described next.

2. Node framework detection (package.json dependencies). For Node projects that build through Nixpacks, Temps reads dependencies and devDependencies to pick a framework-specific start command. It checks in this order, first match wins: astro, next, @nestjs/core, nuxt, @remix-run/react, vite, vue, express. Anything else is treated as generic Node.js and left to Nixpacks' own defaults.

All non-Dockerfile builds use Nixpacks — a build system that generates a Docker image from your source code without requiring a Dockerfile.


Deploy guides

Step-by-step tutorials for each framework: Next.js, React, Vue.js, Angular, Astro, SvelteKit, Remix, Node.js, Django, FastAPI, Laravel, Ruby on Rails, Go, Rust.


JavaScript and TypeScript

Only these five JavaScript presets are detected from repository files:

PresetDetected fromDefault port
Next.js (nextjs)next.config.js, next.config.ts, or next.config.mjs3000
Vite (vite) — React, Vue, SvelteKitvite.config.ts or vite.config.js5173
Create React App (react-app)a react-scripts entry in package.json3000
Docusaurus (docusaurus)docusaurus.config.js or docusaurus.config.ts3000
Rsbuild (rsbuild)rsbuild.config.ts3000

Every other Node project — Astro, Nuxt, Remix without a Vite config, NestJS, Express, Angular, or a plain package.json app — has no file signal. A bare package.json does not select a preset on its own, so these need nixpacks-node (or nixpacks) chosen on the project. Once the build is running, the dependency detection below tunes the start command.

Default port is the preset's metadata value — what Temps records as the port your app listens on. Two things override it at build time. First, any Node project that receives a start command from the table below also receives PORT=3000, so a Vite app runs on 3000 rather than the 5173 its metadata reports. Second, Vite and Docusaurus build static output served by nginx rather than a Node process — Docusaurus's image exposes 3000 as shown, but Vite's serves on port 80.

Start commands

For Node projects built through Nixpacks, Temps writes a nixpacks.toml before the build to set a framework-appropriate start command and HOST=0.0.0.0, so the process binds inside the container:

Dependency detectedStart command
astronpm run preview -- --host 0.0.0.0
vite, vuenpm run preview -- --host 0.0.0.0 --port $PORT
@nestjs/corenode dist/main.js
nuxtnode .output/server/index.mjs
@remix-run/reactnpm run start
expressnode server.js

Next.js and generic Node.js get no override — Nixpacks infers the command from your package.json (Next.js already builds to optimised standalone output). The Express override assumes an entrypoint at server.js; if yours is elsewhere, set the start command explicitly on the deployment.

Package manager detection

Nixpacks detects your package manager from lockfiles:

LockfilePackage manager
bun.lockb or bun.lockBun
pnpm-lock.yamlpnpm
yarn.lockYarn
package-lock.jsonnpm

Node.js version

Nixpacks reads the Node.js version from the first of these that is set:

  1. a NODE_VERSION config variable
  2. engines.node in package.json
  3. .nvmrc
  4. .node-version
  5. Default: Node 18

Python

Any of requirements.txt, pyproject.toml, setup.py or Pipfile selects the single python preset, which delegates the build to Nixpacks' Python provider. There is no separate Django, Flask or FastAPI preset — the framework only affects the start command Nixpacks derives:

ConditionStart command
manage.py and a django dependencypython manage.py migrate && gunicorn <wsgi-app>
a main.py filepython main.py
pyproject.toml with an entry pointthat command, or python -m <module>
none of the aboveno start command — set one on the deployment

The python preset reports a default port of 8000.

Flask and FastAPI get no special handling — Nixpacks has no Flask or FastAPI detection and never generates a uvicorn command. A FastAPI app is started by whichever rule above matches, so give it a main.py or a pyproject.toml entry point, or set the start command explicitly.

Python version

Read from the first of these that is set:

  1. a PYTHON_VERSION config variable
  2. .python-version
  3. runtime.txt

Dependency files

FileTool
requirements.txtpip
PipfilePipenv
pyproject.tomlPoetry or pip
setup.pypip

Go

Detection signalBuild commandDefault portDeploy guide
go.modgo build -o ./bin/app .8080Deploy Go

Go version is read from go.mod. Nixpacks compiles to a static binary and runs it.


Rust

Detection signalBuild commandDefault portDeploy guide
Cargo.tomlcargo build --release8080Deploy Rust

Rust toolchain version is read from rust-toolchain.toml or rust-toolchain. Nixpacks uses a multi-stage build to keep the final image small.


PHP

Once a Nixpacks PHP build is selected, its provider recognises composer.json or index.php and serves the app through nginx and php-fpm. PHP version comes from the require.php field in composer.json, defaulting to 8.2.

Laravel is recognised by the provider — it applies a Laravel-specific nginx configuration and runs a prestart check for missing environment variables. There is no separate Laravel preset to select; choose nixpacks-php and the provider handles it.


Ruby

Once a Nixpacks Ruby build is selected, its provider detects the Gemfile. Rails apps are recognised and started with bundle exec rails server -b 0.0.0.0 -p ${PORT:-3000}; the provider also handles the asset pipeline and bootsnap when those are present.

Ruby version is read from the RUBY_VERSION config variable, then .ruby-version, then a ruby '…' line in the Gemfile. If none of those specify a version the build fails asking for a .ruby-version file — Ruby has no default.

Sinatra gets no special handling; it runs as a generic Ruby app.


Docker

If a Dockerfile is present in the repository root (or the configured app directory), Temps uses it directly instead of Nixpacks.

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

The EXPOSE directive determines the port Temps routes traffic to. If not specified, Temps uses the environment or project exposed_port setting (default: 3000).

Multi-stage builds

Multi-stage Dockerfiles work as expected:

FROM node:20 AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]

Static sites

A bare index.html is not a detection signal — a repository of loose static files fails auto-detection like any other unrecognised project. Select the nixpacks-static preset for it.

Presets that produce static output — vite, docusaurus, and nixpacks-static — take a different deployment path from server apps. Temps still builds a container image, then extracts the build output directory from that image and persists the files, and the proxy serves them directly. No container is left running afterwards, but one is still built to produce the assets.


Override detection

If Temps detects the wrong framework, override it in project settings:

  1. Open your project in the dashboard
  2. Go to Settings
  3. Change the Framework Preset to the correct one
  4. Optionally set a custom Build Command and Start Command

You can also set a custom install command, build command, or app directory for monorepos.

Was this page helpful?