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:
- Docker Compose — a recognised compose file
- Dockerfile
- Framework config files —
docusaurus.config.js/.ts,next.config.js/.mjs/.ts,vite.config.js/.ts,rsbuild.config.ts, or areact-scriptsentry insidepackage.json - Language manifests —
Cargo.toml,go.mod,requirements.txt/pyproject.toml/setup.py/Pipfile,pom.xml/build.gradle/build.gradle.kts - Nixpacks — only when an explicit
nixpacks.tomlis 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:
| Preset | Detected from | Default port |
|---|---|---|
Next.js (nextjs) | next.config.js, next.config.ts, or next.config.mjs | 3000 |
Vite (vite) — React, Vue, SvelteKit | vite.config.ts or vite.config.js | 5173 |
Create React App (react-app) | a react-scripts entry in package.json | 3000 |
Docusaurus (docusaurus) | docusaurus.config.js or docusaurus.config.ts | 3000 |
Rsbuild (rsbuild) | rsbuild.config.ts | 3000 |
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 detected | Start command |
|---|---|
astro | npm run preview -- --host 0.0.0.0 |
vite, vue | npm run preview -- --host 0.0.0.0 --port $PORT |
@nestjs/core | node dist/main.js |
nuxt | node .output/server/index.mjs |
@remix-run/react | npm run start |
express | node 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:
| Lockfile | Package manager |
|---|---|
bun.lockb or bun.lock | Bun |
pnpm-lock.yaml | pnpm |
yarn.lock | Yarn |
package-lock.json | npm |
Node.js version
Nixpacks reads the Node.js version from the first of these that is set:
- a
NODE_VERSIONconfig variable engines.nodeinpackage.json.nvmrc.node-version- 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:
| Condition | Start command |
|---|---|
manage.py and a django dependency | python manage.py migrate && gunicorn <wsgi-app> |
a main.py file | python main.py |
pyproject.toml with an entry point | that command, or python -m <module> |
| none of the above | no 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:
- a
PYTHON_VERSIONconfig variable .python-versionruntime.txt
Dependency files
| File | Tool |
|---|---|
requirements.txt | pip |
Pipfile | Pipenv |
pyproject.toml | Poetry or pip |
setup.py | pip |
Go
| Detection signal | Build command | Default port | Deploy guide |
|---|---|---|---|
go.mod | go build -o ./bin/app . | 8080 | Deploy Go |
Go version is read from go.mod. Nixpacks compiles to a static binary and runs it.
Rust
| Detection signal | Build command | Default port | Deploy guide |
|---|---|---|---|
Cargo.toml | cargo build --release | 8080 | Deploy 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
Temps does not auto-detect PHP projects — neither composer.json nor index.php is a preset detection signal. A PHP repository fails detection with "Could not auto-detect project type from files". Select the nixpacks-php preset (or nixpacks for auto-detection) on the project before deploying.
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
Temps does not auto-detect Ruby projects — a Gemfile is not a preset detection signal, so a Ruby repository fails detection. Select the nixpacks-ruby preset (or nixpacks for auto-detection) on the project before deploying.
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:
- Open your project in the dashboard
- Go to Settings
- Change the Framework Preset to the correct one
- Optionally set a custom Build Command and Start Command
You can also set a custom install command, build command, or app directory for monorepos.