RepoPilotOpen in app →

railwayapp/nixpacks

App source + Nix packages + Docker = Image

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 3d ago
  • 31+ active contributors
  • Distributed ownership (top contributor 38% of recent commits)
Show all 6 evidence items →
  • MIT licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/railwayapp/nixpacks)](https://repopilot.app/r/railwayapp/nixpacks)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/railwayapp/nixpacks on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: railwayapp/nixpacks

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/railwayapp/nixpacks shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 3d ago
  • 31+ active contributors
  • Distributed ownership (top contributor 38% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live railwayapp/nixpacks repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/railwayapp/nixpacks.

What it runs against: a local clone of railwayapp/nixpacks — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in railwayapp/nixpacks | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 33 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>railwayapp/nixpacks</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of railwayapp/nixpacks. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/railwayapp/nixpacks.git
#   cd nixpacks
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of railwayapp/nixpacks and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "railwayapp/nixpacks(\\.git)?\\b" \\
  && ok "origin remote is railwayapp/nixpacks" \\
  || miss "origin remote is not railwayapp/nixpacks (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "src/main.rs" \\
  && ok "src/main.rs" \\
  || miss "missing critical file: src/main.rs"
test -f "src/lib.rs" \\
  && ok "src/lib.rs" \\
  || miss "missing critical file: src/lib.rs"
test -f "Cargo.toml" \\
  && ok "Cargo.toml" \\
  || miss "missing critical file: Cargo.toml"
test -f ".github/workflows/ci.yml" \\
  && ok ".github/workflows/ci.yml" \\
  || miss "missing critical file: .github/workflows/ci.yml"
test -f "docs/pages/docs/configuration/file.md" \\
  && ok "docs/pages/docs/configuration/file.md" \\
  || miss "missing critical file: docs/pages/docs/configuration/file.md"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 33 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~3d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/railwayapp/nixpacks"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Nixpacks generates OCI-compliant Docker images by combining application source code with Nix packages and a minimal base image (Debian/Ubuntu). It replaces Cloud Foundry Buildpacks with a Nix-based dependency resolution system, allowing declarative specification of system and language packages without complex detection logic. Monorepo structure: primary binary in src/main.rs and library in src/lib.rs (single crate), build system in Makefile and .cargo/config.toml. Base container definitions live in base/debian/ and base/ubuntu/. Test infrastructure uses insta snapshots (dev-dependencies) and test-helper workspace member. Extensive workflows in .github/workflows/ for CI, publishing, and nixpkgs-archive updates.

👥Who it's for

Platform engineers and deployment system maintainers (like those at Railway) who need to build production container images from arbitrary app source code and want deterministic, reproducible builds using the Nix ecosystem instead of traditional buildpack inference.

🌱Maturity & risk

Actively maintained but in maintenance mode (per README—not under active development). The codebase is well-structured with CI/CD workflows (.github/workflows/), Rust 1.70+ requirement, and appears production-proven at Railway scale. However, the project recommends adopting Railpack as a replacement for new use cases.

Moderate risk: the project is explicitly in maintenance mode and not actively developed, increasing the risk of stale dependencies (400+ Rust dependencies in Cargo.lock). Single-maintainer governance under Railway's control. Breaking changes are possible before 1.0.0 (currently at 1.41.0). Nix ecosystem complexity and the Rust compiler dependency add operational friction.

Active areas of work

Project is in maintenance mode per README—no active feature development. Recent activity appears to focus on dependency updates (evidenced by dependabot.yml) and nixpkgs-archive synchronization (.github/workflows/update-nixpkgs-archive.yml). No indication of major new features; direction is toward Railpack replacement.

🚀Get running

git clone https://github.com/railwayapp/nixpacks.git
cd nixpacks
cargo build --release
./target/release/nixpacks --help

Optionally use the dev container: open in VS Code with Remote Containers extension (configured in .devcontainer/devcontainer.json).

Daily commands: Development: cargo run -- <args> or use Makefile targets. Build production binary: cargo build --release. Run dev server (if Actix-web enabled): check src/main.rs for server startup. Tests: cargo test (uses insta snapshots and test-helper).

🗺️Map of the codebase

  • src/main.rs — Entry point for the CLI binary; defines command-line interface and top-level build orchestration
  • src/lib.rs — Main library interface exposing core build, detection, and image generation logic
  • Cargo.toml — Project manifest defining dependencies (anyhow, clap, colored, walkdir, globset) and workspace structure
  • .github/workflows/ci.yml — Continuous integration pipeline validating builds, tests, and release artifacts
  • docs/pages/docs/configuration/file.md — Documentation for the core nixpacks.toml configuration schema that users must understand
  • base/debian/Dockerfile — Base runtime image definition used as foundation for all generated OCI images
  • Makefile — Build automation and local development tasks for compiling and testing the Rust project

🧩Components & responsibilities

  • Provider Detection Engine (globset, walkdir, Rust pattern matching) — Scans source directory using globset patterns to identify programming language and framework; returns matched provider or error
    • Failure mode: No provider matches → build fails with helpful error message; user must explicitly specify provider via nixpacks.toml
  • Language Providers (Rust trait polymorphism, Nix expressions) — Abstract trait implementations for each language (Node, Python, Go, Rust, etc.); defines build phases, Nix dependencies, and entry point logic
    • Failure mode: Provider build phase fails → Docker build halts; user must debug via logs and provider documentation
  • Build Phase Orchestrator — Chains provider

🛠️How to make changes

Add Support for a New Programming Language

  1. Create a new provider module in src/providers/{language}.rs implementing the Provider trait (src/providers/{language}.rs)
  2. Register the provider in src/providers/mod.rs and detection logic (src/providers/mod.rs)
  3. Add language-specific Nix expressions and build phases (src/providers/{language}/nix.rs)
  4. Create user documentation at docs/pages/docs/providers/{language}.md (docs/pages/docs/providers/{language}.md)
  5. Add test cases and example projects in test fixtures (test-helper/examples/{language}/)

Add a New Configuration Option

  1. Update the configuration schema struct in src/config.rs (src/config.rs)
  2. Update documentation for the configuration file format (docs/pages/docs/configuration/file.md)
  3. Implement handling logic in the relevant provider or build phase (src/build.rs)
  4. Add test cases validating the new configuration (src/config.rs)

Add a Deployment Integration Guide

  1. Create new deployment guide documentation (docs/pages/docs/deploying/{platform}.md)
  2. Add example workflow or configuration snippets (docs/pages/docs/deploying/{platform}.md)
  3. Link the guide from docs/pages/docs/deploying/ index (docs/pages/docs/deploying/)

🔧Why these technologies

  • Rust — Provides fast, memory-safe compilation and CLI tooling; critical for build-time performance when processing thousands of user apps
  • Nix package manager — Declarative system and language dependency management; avoids buildpacks' complexity by leveraging Nix ecosystem's reliable, composable package definitions
  • Docker/OCI image format — Universal deployment standard; generated images work across any OCI-compliant runtime (Kubernetes, Docker, Podman, containerd)
  • clap CLI framework — Structured, derive-based argument parsing; reduces boilerplate for build, generate, and config subcommands
  • Next.js documentation site — Modern, static-generated documentation; supports Markdoc for custom syntax and easy navigation for users learning provider support

⚖️Trade-offs already made

  • Maintenance mode—not under active development

    • Why: Shift to Railpack as the recommended replacement; reduces maintenance burden while keeping Nixpacks available for existing users
    • Consequence: New language providers and features may lag; community contributions welcome but core team limited
  • Nix-based dependency resolution over language-native package managers

    • Why: Nix provides reproducible, isolated builds independent of language ecosystem fragmentation; avoids npm/pip version drift issues
    • Consequence: Steeper learning curve for users unfamiliar with Nix; Nix ecosystem must be kept up-to-date via GitHub Actions
  • Multi-provider detection via file pattern matching

    • Why: Language-agnostic; single codebase handles 20+ languages without hardcoding language-specific logic
    • Consequence: Ambiguous projects (e.g., monorepos with multiple package.json files) may require explicit configuration in nixpacks.toml
  • Layered image caching strategy

    • Why: Improves rebuild performance by preserving dependency layers; reduces image push/pull overhead
    • Consequence: Requires careful orchestration of Nix build phases; misconfiguration can bloat image size or invalidate caches

🚫Non-goals (don't propose these)

  • Real-time application monitoring or observability
  • In-app authentication or secrets management (users must integrate external tools)
  • Language runtime optimization beyond Nix package defaults
  • GUI-based build configuration (CLI and TOML-only)

🪤Traps & gotchas

No direct SQL/database dependency, but Nix build dependencies are implicit—build failures may stem from missing nix CLI or wrong nixpkgs-archive version. Actix-web integration (in dependencies) suggests server mode exists but may not be documented in top-level README. Breaking changes likely between versions (pre-1.0.0 semver); check CHANGELOG before upgrading. Maintenance mode risk: dependency updates may lag; plan for potential security patches to Rust deps. Path handling uses path-slash crate, suggesting Windows cross-platform builds need attention.

🏗️Architecture

💡Concepts to learn

  • OCI Image Spec — Nixpacks generates OCI-compliant images as its core output; understanding the spec (image format, layer structure, config) is essential to debugging image generation
  • Nix Expression Language — Nixpacks converts app configs into Nix expressions to declare dependencies; reading generated nix code and writing custom nix is likely in advanced usage
  • Multi-stage Docker Build — Nixpacks likely generates multi-stage Dockerfiles to minimize image size; understanding layer caching and build optimization is crucial for performance tuning
  • Language Provider Pattern — Nixpacks detects and configures languages via a provider/detector abstraction (visible in architecture); contributors must understand this pattern to add new language support
  • Snapshot Testing — Dev dependencies include insta for snapshot testing; nixpacks uses snapshots to validate generated image configs—understanding snapshot semantics is needed for modifying test assertions
  • Buildpack Specification — Nixpacks was designed as a buildpack alternative; familiarity with buildpack concepts (detect phase, build phase, launch layer) helps understand the design rationale
  • Nix Flakes — Modern Nix dependency management; nixpacks may use or generate flake.nix files for reproducible builds—understanding flakes helps with advanced nixpacks usage
  • railwayapp/railpack — Explicit successor project recommended in README; represents the future direction for Railway deployments
  • NixOS/nixpkgs — Upstream Nix package repository that nixpacks depends on; updates managed via update-nixpkgs-archive workflow
  • buildpacks/pack — Original Cloud Foundry Buildpacks implementation; nixpacks was designed as an alternative to address its limitations
  • nix-community/nixpkgs-docker — Ecosystem tooling for building Docker images with Nix; relevant for understanding output image generation
  • container-tools/umoci — OCI image manipulation toolkit; likely used or inspirational for nixpacks' OCI compliance

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for language detection and provider matching

The repo appears to support multiple languages (Node, Python, Rust, etc.) based on the Cargo.toml dependencies and nix provider structure, but there's no visible comprehensive integration test suite in the file structure. The test-helper workspace member suggests testing infrastructure exists, but no concrete test files are shown. Adding integration tests would ensure new language providers and detection logic don't regress.

  • [ ] Create tests/integration/ directory structure mirroring src/providers
  • [ ] Add test cases in tests/integration/ for each language provider (Python, Node, Rust, etc.) that verify: (1) correct language detection from source, (2) correct Nix dependencies selected, (3) correct Docker build output
  • [ ] Reference src/main.rs and src/lib.rs entry points to understand the detection flow
  • [ ] Use test-helper crate as foundation and add fixtures in tests/fixtures/ with sample app structures
  • [ ] Add integration test invocation to .github/workflows/ci.yml if not present

Document CLI commands and configuration options in docs/pages/docs/

The docs structure shows docs/pages/docs/cli.md exists but the file list is truncated. The Cargo.toml shows clap is a major dependency for CLI, suggesting the CLI is complex. Contributing comprehensive CLI documentation with examples for each major command (build, plan, etc.) would be high-value for users and maintainers.

  • [ ] Review current docs/pages/docs/cli.md and identify missing command documentation
  • [ ] Create/expand docs for key commands by parsing clap derive attributes from src/main.rs
  • [ ] Add real examples in docs/pages/docs/examples/ showing: (1) building a Node app, (2) building a Python app, (3) custom Nix package injection
  • [ ] Document environment variables and configuration file format (CONTRIBUTING.md hints at this)
  • [ ] Add cross-references to the configuration page

Add GitHub Actions workflow for testing multiple Rust versions and platforms

The README specifies 'Rust: 1.70+' and Cargo.toml specifies 'rust-version = 1.60', suggesting the project maintains compatibility. The .github/workflows/ci.yml likely exists but the file contents aren't shown. Adding a matrix build job testing against multiple Rust versions (1.60, MSRV, current stable, nightly) and platforms (Linux, macOS, Windows) would catch regressions early.

  • [ ] Review .github/workflows/ci.yml current configuration
  • [ ] Add a new job with Rust version matrix: ["1.60", "stable", "nightly"] and os matrix: [ubuntu-latest, macos-latest, windows-latest]
  • [ ] Configure the job to run 'cargo build --all' and 'cargo test --all' for each combination
  • [ ] Add allow-failure for nightly builds to avoid blocking merges
  • [ ] Update README.md to document the MSRV guarantee (1.60) if not already present

🌿Good first issues

  • Add integration tests for base/debian/Dockerfile and base/ubuntu/Dockerfile builds (currently no test/ directory visible covering base image validation): Base images are critical to reproducibility; automated testing would catch regressions early
  • Document Actix-web server mode in README.md (dependencies show 'actix-web': '4.2.1' but no docs on how to run server vs CLI): Users may not discover server functionality; clarity would improve adoption
  • Create a 'Migrating from Cloud Foundry Buildpacks to Nixpacks' guide in docs/ (docs structure exists but no comparison/migration docs visible): Target audience likely has buildpack experience; a migration guide would ease adoption

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 144b4f9 — Add maintenance mode notice and recommend Railpack (#1378) (iloveitaly)
  • 81be35a — chore: Release (coffee-cup)
  • 58a7c4d — Add Node 24 support and refactor version-to-archive mapping (#1373) (coffee-cup)
  • 1234b3b — chore(deps): bump actions/stale from 9 to 10 (#1362) (dependabot[bot])
  • c0c0ff1 — chore(deps): bump actions/setup-node from 3 to 5 (#1361) (dependabot[bot])
  • 1dd9288 — Add maintenance mode notices to README and docs (#1365) (coffee-cup)
  • 260c497 — chore: Release (coffee-cup)
  • e52d523 — Adds nx 20 support (#1355) (ntgussoni)
  • 2819b0a — fix: resolve clippy warnings for code quality (#1364) (coffee-cup)
  • f51d7fd — Update Bun to stable status and nixpkgs archive (#1350) (coffee-cup)

🔒Security observations

The nixpacks codebase

  • Medium · Outdated Rust Version Requirement — Cargo.toml. The project specifies rust-version = '1.60' in Cargo.toml, but the README indicates Rust 1.70+ is required. This discrepancy may allow builds with vulnerable compiler versions that lack security fixes. Fix: Update rust-version to '1.70' to match the documented minimum requirement and ensure security patches are included.
  • Medium · Outdated Dependency Versions — Cargo.toml. Several dependencies use older versions that may contain known vulnerabilities: actix-web 4.2.1 (released 2022), tokio 1.23.0 (2022), and others. No lockfile version restrictions are specified for some dependencies. Fix: Run 'cargo audit' to identify known vulnerabilities. Update dependencies to their latest versions and consider using cargo-deny to prevent known vulnerable versions.
  • Medium · Insecure Deserialization — Cargo.toml (serde, serde_json, serde_yaml dependencies). The codebase includes serde with default features enabled and serde_yaml, serde_json for parsing untrusted input. YAML parsing in particular is vulnerable to code execution if not carefully configured. Fix: Review all YAML/JSON parsing code for untrusted input. Consider using deny_unknown_fields and validate all deserialized data. Use serde's safer default settings.
  • Medium · Process Execution Risk — Cargo.toml (tokio, wait-timeout dependencies), src/main.rs. The project uses tokio and wait-timeout for process execution, suggesting subprocess spawning. Combined with app source handling, this could allow arbitrary code execution if user input is not properly sanitized. Fix: Audit all subprocess invocations for command injection. Use explicit argument lists instead of shell commands. Validate and sanitize all user-provided paths and arguments.
  • Low · Weak Random Number Generation — Cargo.toml (rand dependency). The 'rand' crate is used without specification of a cryptographically secure RNG. Default rand implementations may not be suitable for security-sensitive operations. Fix: If rand is used for security purposes (e.g., token generation), explicitly use rand::rngs::OsRng or similar cryptographically secure sources. Document the intended use case.
  • Low · File System Traversal Risk — Cargo.toml (walkdir, globset dependencies), src/ (likely). The project uses walkdir and globset for file operations. Without proper validation, this could allow directory traversal attacks when processing user-provided paths. Fix: Validate and canonicalize all file paths. Use path-slash carefully and ensure path operations don't escape intended boundaries. Implement whitelist-based path validation.
  • Low · Missing Security Headers in Web Server — src/ (implementation not fully visible). The project uses actix-web but no obvious security middleware configuration is visible in the file structure. Default actix-web deployments may lack security headers. Fix: Implement security middleware for actix-web including: X-Frame-Options, X-Content-Type-Options, Content-Security-Policy, Strict-Transport-Security headers.
  • Low · Potential Information Disclosure via Error Messages — Cargo.toml (anyhow, colored, console dependencies). The use of anyhow for error handling with colored console output suggests detailed error messages. These may expose sensitive path information or system details to users. Fix: Implement error handling that provides user-friendly messages while logging detailed errors server-side. Avoid exposing file paths or system configuration in user-facing output.
  • Low · Maintenance Mode Risk — README.md. The README explicitly states the project is in 'maintenance mode' and not under active development. This means security vulnerabilities may not be patched promptly. Fix: Evaluate if the project meets your organization's security requirements. Plan for migration to the recommended Railpack replacement. Implement additional security controls if continuing to use this project.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · railwayapp/nixpacks — RepoPilot