Skip to content

Supported Languages & Frameworks ​

Infrly builds and runs your app for you — you don't write a Dockerfile yourself. Pick a runtime and Infrly prefills sensible install/build/start commands and a default port; override any of them if your app doesn't match the default shape.

RuntimeInstall commandBuild commandStart commandDefault port
Node.jsnpm install (or yarn install / pnpm install, detected)npm run buildnpm start3000
Pythonpip install -r requirements.txt(none)uvicorn main:app --host 0.0.0.0 --port $PORT8000
Gogo mod downloadgo build -o app ../app8080
Java(none — Maven handles it)mvn clean package -DskipTestsjava -jar target/*.jar8080
Rubybundle install(none)bundle exec puma -b tcp://0.0.0.0:$PORT3000
PHPcomposer install --no-dev --optimize-autoloader(none)php -S 0.0.0.0:$PORT8000
Rust(none — Cargo handles it)cargo build --release./target/release/app8080

Every default already reads the port from $PORT — see Build & Start Commands for why that matters and how to override any of these fields.

Supported runtime versions ​

Infrly reads the version your project asks for, builds with a matching official runtime image, and shows the choice at the top of every build log (for example Using Node.js 22 (from engines.node in package.json)). The same rules apply to Web Services, Static Sites and Cron Jobs.

RuntimeSupported versionsUsed when nothing is specifiedWhere Infrly looks (first match wins)
Node.js20, 22, 24, 2622engines.node in package.json, .nvmrc, .node-version, .tool-versions
Python3.6 – 3.143.12.python-version, runtime.txt, requires-python or Poetry's python in pyproject.toml, Pipfile, .tool-versions
Java11, 17, 21, 2521pom.xml (maven.compiler.release, java.version, maven.compiler.source/target, compiler plugin), Gradle toolchain / jvmToolchain / sourceCompatibility, .java-version, system.properties
Goany go.mod version (built with Go 1.22 – 1.26)1.25go and toolchain in go.mod
Ruby3.1 – 3.43.3.ruby-version, ruby in Gemfile, Gemfile.lock, .tool-versions
PHP8.1 – 8.58.3config.platform.php or require.php in composer.json
Rustlatest stablelatest stablerust-toolchain.toml / rust-toolchain is installed automatically

How versions are chosen:

  • Ranges (">=18", "^3.10", "^7.3|^8.0") get the default version when it fits, otherwise the closest supported version that fits. "20.x" means exactly Node.js 20.
  • Exact pins (.python-version 3.11.4) use that minor line with its latest patch. Ruby is the exception: an exact Ruby version (3.2.2) is used exactly, because Bundler requires it.
  • Java builds with the smallest supported JDK at or above your target (a 19 target builds on JDK 21).
  • Go builds older go.mod versions with the current Go release, since newer Go compiles older code unchanged.

Unsupported versions stop the deployment before anything is built, with a message that says what was found, where, and what to use instead. For example:

Unsupported Node.js version: 18 (from engines.node in package.json). Infrly supports Node.js 20 and higher. Please update your project to a supported version.

The same check runs when you pick a repository in the dashboard, so you see the problem before creating the service. To fix it, update the version in the file named in the message, push, and deploy again.

Node.js: package managers and versions ​

Infrly supports npm, npx, Yarn (1 and 2+) and pnpm out of the box. When you pick a repository, it detects which one your project uses and prefills matching commands:

Your repository hasPackage managerInstall commandBuild / start
"packageManager": "pnpm@…" or pnpm-lock.yamlpnpmpnpm installpnpm run build / pnpm run start
"packageManager": "yarn@…" or yarn.lockYarnyarn installyarn run build / yarn run start
package-lock.json, or nothingnpmnpm installnpm run build / npm run start
  • Exact versions: the packageManager field in package.json (for example "pnpm@10.18.0" or "yarn@4.10.3") is honored exactly, through Node.js's built-in Corepack. Without it, Yarn 1 and the current pnpm are used.
  • Lockfiles are respected. The default install commands don't fail if your lockfile is slightly out of date; for strict, lockfile-only installs, set the install command to npm ci, yarn install --frozen-lockfile (Yarn 1), yarn install --immutable (Yarn 2+) or pnpm install --frozen-lockfile.
  • npx works in any command, for example a build command of npx vite build or a start command of npx serve -s dist -l $PORT. Packages that aren't in your dependencies are downloaded automatically, without a prompt.
  • Node.js version: set "engines": { "node": "…" } in package.json (or use .nvmrc). See Supported runtime versions: Node.js 18 and older can't be deployed.
  • Bun isn't supported as a build tool yet. Projects with a bun.lockb are prefilled with npm commands instead.

Framework notes ​

  • Node.js — the default start shape fits Express, Fastify, Koa, NestJS, or a custom server.js, as long as package.json has a start script. Nuxt is detected automatically: as a Web Service it starts with node .output/server/index.mjs; as a Static Site it builds with your generate script and publishes .output/public. A Next.js app needs npm run build to already produce a production server your start command runs (next start), not a static export — if you're exporting fully static HTML instead, deploy it as a Static Site rather than a Web Service.
  • Python — the default start command assumes an ASGI app object named app in main.py (the common FastAPI shape). Override it for Django (gunicorn myproject.wsgi -b 0.0.0.0:$PORT) or Flask (gunicorn app:app -b 0.0.0.0:$PORT) — both need gunicorn (or another WSGI/ASGI server) in requirements.txt since Flask/Django's own dev server isn't meant for production traffic.
  • Go — works unmodified with Gin, Echo, Fiber, or the standard library net/http — whatever your go build output binds to $PORT.
  • Java — Maven projects run the executable JAR in target/. For Gradle, Infrly builds with ./gradlew build -x test (making gradlew executable first) and starts the Spring Boot JAR in build/libs/, skipping the -plain.jar Gradle also produces.
  • Ruby — fits Rails and Sinatra out of the box via Puma. Infrly sets RACK_ENV=production and RAILS_ENV=production by default (set your own value to override). A Rails app also needs SECRET_KEY_BASE, and usually its database migrated before serving traffic — see whether your framework needs a release/migration step in its start command.
  • PHP — the built-in php -S server is fine for smaller Laravel/Symfony apps; higher-traffic apps typically want php-fpm behind a real web server instead, which means a custom start command.
  • Rust — works with Actix Web, Axum, Rocket, or anything else that binds to $PORT; cargo build --release is slower than a debug build but is what you want for anything actually serving traffic.

Something else entirely? ​

If your app doesn't fit any of these seven runtimes as-is, the most common workaround is wrapping it to match one — e.g. a compiled binary from another language can often still be started via a thin script under whichever runtime's start command shape fits closest. If that genuinely doesn't work for your stack, reach out — new runtime support is straightforward to add on Infrly's side.

Next ​

Infrly — You commit. We ship. Need something custom? support@infrlyapp.com