How I Built ForgeKit: An Open-Source Engineering Acceleration Platform That Scaffolds Production-Ready Projects in Under 60 Seconds
Every engineer has lost a Monday morning to wiring up the same Dockerfile, the same GitHub Actions workflow and the same ESLint config they wrote three projects ago. ForgeKit eliminates that entirely. One command. Production-ready project.

A versatile DevSecOps Engineer specialized in creating secure, scalable, and efficient systems that bridge development and operations. My expertise lies in automating complex processes, integrating AI-driven solutions, and ensuring seamless, secure delivery pipelines. With a deep understanding of cloud infrastructure, CI/CD, and cybersecurity, I thrive on solving challenges at the intersection of innovation and security, driving continuous improvement in both technology and team dynamics.
https://github.com/SubhanshuMG/ForgeKit
The Problem Nobody Talks About Honestly
It is 9 AM on a Monday. Your team just got greenlit on a new microservice. You spin up a fresh repo and then spend the next three hours doing this:
You copy the Dockerfile from the last project. Strip out service-specific stuff. Realize you forgot the health check. Set up GitHub Actions from a Stack Overflow template that still references Node 16, which hit EOL two years ago. Wire up ESLint, then discover your team standardized on a different config six months ago. Create
.env.example, forget two variables, find out at 11 PM during code review.
You have not written a single line of product code.
This compounds across every new project, every new contributor onboarding, every side project started at 10 PM that burns out before the interesting part begins. It is not a skill problem. It is a tooling problem.
Engineers lose 2+ hours on every new project to the exact same setup work. ForgeKit eliminates it in one command.
What ForgeKit Is
ForgeKit is an open-source engineering acceleration platform. One command scaffolds a fully wired, production-ready project: Dockerfile, docker-compose, GitHub Actions CI, test setup, environment config, health endpoint, and stack-specific sensible defaults.
forgekit new my-api --template api-service
No config to set up. No template repos to fork and clean. The project runs on the first try.
It ships as a TypeScript monorepo published to npm, with six production-grade templates and a React 18 + Vite web dashboard for browsing and launching scaffolds visually.
Real-World Example: Zero to Running FastAPI Service
Say you are an ML engineer who needs a FastAPI service to expose a model endpoint. The usual path: virtualenv setup, remembering pydantic v2 syntax changes, SQLAlchemy async session wiring, getting the multi-stage Docker build right so the image is not 2 GB, writing CI from scratch.
With ForgeKit:
npm install -g forgekit-cli
forgekit new model-serving-api --template api-service
ForgeKit, Engineering Acceleration Platform
Scaffolding model-serving-api from template api-service...
✓ Scaffolded 14 files in 1.2s
Next steps:
cd model-serving-api
pip install -r requirements.txt
cp .env.example .env
docker-compose up
What gets generated
| File | What it does |
|---|---|
main.py |
FastAPI app entrypoint with router |
app/config.py |
Pydantic Settings, env var loading |
app/database.py |
SQLAlchemy async session factory |
app/routes/health.py |
/health endpoint with typed response |
tests/test_health.py |
Pytest test passes immediately |
Dockerfile |
Multi-stage build, non-root user |
docker-compose.yml |
App + PostgreSQL with healthcheck |
.env.example |
Every variable documented |
Everything runs. Tests pass. Docker image builds clean. You are building your actual product within minutes.
All Six Templates
| Template | Stack | Use Case |
|---|---|---|
web-app |
Node.js + React + TypeScript + Express + Vite | Full-stack web apps |
api-service |
Python + FastAPI + PostgreSQL + Docker | REST APIs, ML serving |
ml-pipeline |
Python + Jupyter + MLflow + scikit-learn | Reproducible ML experiments |
next-app |
Next.js + Tailwind + TypeScript | Frontend-first apps |
go-api |
Go + Gin + PostgreSQL | High-performance APIs |
serverless |
AWS Lambda + TypeScript | Event-driven functions |
Every template ships with a Dockerfile, docker-compose, .env.example, and at least one passing test.
Architecture
ForgeKit is not a glorified cp -r. It has a clean five-layer architecture built for security and extensibility.
| Layer | Responsibility | Key Modules |
|---|---|---|
| Interface | User interaction, CLI prompts, web dashboard | packages/cli/, packages/web/ |
| Application | Orchestration, validation, execution tracking | commands/new.ts, core/validator.ts |
| Service | Scaffolding engine, template resolver, file writer, security guard | core/scaffold.ts, core/security.ts |
| Data | Template registry, audit logs, config | templates/registry.json, core/audit.ts |
| Infrastructure | CI/CD, npm publishing, docs hosting | .github/workflows/, docs/ |
The Scaffold Lifecycle
When you run forgekit new, here is exactly what happens under the hood:
forgekit new
→ sanitizeProjectName() [strips to a-z0-9 only]
→ validateTemplateId() [regex + blocks path traversal]
→ getTemplate() [reads registry.json]
→ writeTemplateFiles() [for each file:]
→ validatePathContainment() [blocks ../../ escapes]
→ Handlebars.compile() [renders .hbs templates]
→ fs.outputFile() [writes to disk]
→ validateHookCommand() [allowlist: npm/pip/python only]
→ spawnSync(shell: false) [runs post-scaffold hooks]
→ trackEvent() [opt-out telemetry]
Full source: packages/cli/src/core/
Security by Design
Security is a design constraint, not a checklist item. The core assumption is that templates are untrusted input. A malicious template must not escape the output directory or run arbitrary code.
A template cannot write outside the project root. A hook cannot run
curl | bash. A project name cannot inject a path traversal. These are enforced at the code level, not by convention.
The four defenses
Path traversal prevention validates every destination path against the project root before any write:
// core/security.ts
export function validatePathContainment(
targetRoot: string,
filePath: string
): boolean {
const resolvedRoot = path.resolve(targetRoot);
const resolvedFile = path.resolve(targetRoot, filePath);
return resolvedFile.startsWith(resolvedRoot + path.sep);
}
Command injection prevention via an explicit allowlist. Only npm, npx, yarn, pnpm, pip, pip3, python, and python3 are allowed. spawnSync uses shell: false.
Name sanitization strips everything except [a-z0-9-_]. The string ../../etc/passwd becomes etc-passwd. No special characters reach the filesystem.
External template validation checks github: and npm: prefixed IDs against a strict regex before any network call.
Every generated project ships secure by default
| Default | What it protects against |
|---|---|
Non-root Docker USER appuser |
Container breakout escalation |
.env.example with no real secrets |
Credential leaks in version control |
.gitignore excludes .env |
Accidental secret commits |
| PostgreSQL healthcheck in compose | Startup race conditions |
| Multi-stage Docker builds | Bloated images with build tools exposed |
| Pinned dependency versions | Supply chain drift |
Generated Code That Actually Runs
The health route in every api-service scaffold:
from fastapi import APIRouter
from pydantic import BaseModel
router = APIRouter()
class HealthResponse(BaseModel):
status: str
version: str
@router.get("/health", response_model=HealthResponse)
async def health_check():
return HealthResponse(status="ok", version="0.1.0")
The test that ships alongside it, passing on first run:
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_health_check():
response = client.get("/api/v1/health")
assert response.status_code == 200
assert response.json()["status"] == "ok"
Your CI is green before you write a single line of product code.
https://gist.github.com/SubhanshuMG/29a54512c27445b1d45f07da2d3a40fa
The Template System
Each template is a directory of files. Some are raw (copied as-is), some are Handlebars .hbs files for variable interpolation. The registry at templates/registry.json defines the manifest:
{
"id": "api-service",
"name": "API Service (Python + FastAPI)",
"stack": ["python", "fastapi", "postgresql", "docker"],
"files": [
{ "src": "main.py", "dest": "main.py" },
{ "src": "README.md.hbs", "dest": "README.md" },
{ "src": "Dockerfile", "dest": "Dockerfile" }
],
"hooks": [
{ "type": "post-scaffold", "command": "pip", "args": ["install", "-r", "requirements.txt"] }
]
}
Handlebars files use {{name}} to inject the project name at scaffold time:
# {{name}}
A FastAPI service scaffolded with ForgeKit.
Full registry: templates/registry.json
Testing Strategy
Three layers, each with a specific purpose.
Unit tests cover the security functions: sanitizer, path containment, hook allowlist, template ID regex.
Integration tests scaffold a real project into a temp directory and verify the full file tree:
it("creates all expected files", async () => {
const result = await scaffold({
projectName: "test-api",
templateId: "api-service",
outputDir: os.tmpdir(),
variables: { name: "test-api" },
skipInstall: true,
});
expect(result.success).toBe(true);
expect(result.filesCreated).toContain(
path.join(os.tmpdir(), "test-api", "main.py")
);
});
Smoke tests run the full CLI binary end-to-end against a real filesystem.
Full test suite: packages/cli/src/__tests__
CI/CD Pipeline
Seven GitHub Actions workflows, each with a single job:
| Workflow | Trigger | Purpose |
|---|---|---|
ci.yml |
push, PR | Typecheck + lint + test + build (Node 20/22 matrix) |
publish.yml |
release tag | npm publish, gated on CI |
codeql.yml |
push, schedule | Static analysis |
security-scan.yml |
push | Dependency audit |
dco-check.yml |
PR | Developer Certificate of Origin |
docs.yml |
push to main | VitePress docs to GitHub Pages |
release-drafter.yml |
PR merge | Auto-draft changelog |
Workflows: .github/workflows/
How to Add Your Own Template
Full step-by-step guide (expand)
1. Create the directory: mkdir templates/django-api
2. Add your files (.hbs for Handlebars interpolation):
templates/django-api/
├── manage.py.hbs
├── requirements.txt
├── Dockerfile
├── docker-compose.yml
├── .env.example
└── README.md.hbs
3. Register in templates/registry.json:
{
"id": "django-api",
"name": "Django API",
"stack": ["python", "django", "drf", "postgresql"],
"files": [
{ "src": "manage.py.hbs", "dest": "manage.py" },
{ "src": "Dockerfile", "dest": "Dockerfile" }
],
"hooks": [
{ "type": "post-scaffold", "command": "pip", "args": ["install", "-r", "requirements.txt"] }
]
}
4. Use {{name}} in .hbs files for project name injection.
5. Write a test, open a PR. That is the full loop.
The CLI
# Scaffold (interactive mode)
forgekit new
# Scaffold with flags
forgekit new my-api --template api-service
# Preview without writing files
forgekit new preview --template go-api --dry-run
# List templates
forgekit list
# Check your environment
forgekit doctor
Why Apache 2.0 and DCO
Apache 2.0 over MIT: Includes an explicit patent grant and trademark protection. For an engineering platform, companies will depend on both matters. MIT leaves them ambiguous.
DCO over CLA: A per-commit sign-off (git commit -s) stating you have the right to submit the code. Same legal effect as a CLA, zero friction. Every PR enforces it via dco-check.yml.
Roadmap
| Phase | Status | Focus |
|---|---|---|
| Foundation | Done | Repo structure, governance, CI |
| Day-one value | Done | CLI, 6 templates, web dashboard, npm |
| Multi-role expansion | Next | Rails, Rust/Axum, React Native templates |
| Security + audit | Planned | RBAC, audit log, policy validation |
| Community growth | Planned | Public template registry, contribution pathways |
| Enterprise | Future | Team templates, analytics, self-hosted |
Full roadmap: ROADMAP.md
Get Started
npm install -g forgekit-cli
forgekit new
The repo is public, CI is green, the package is live on npm. Star the repo. Try the CLI. Contribute a template.
https://www.producthunt.com/products/forgekit-2
Contributing
Best first contributions right now:
Add a new template (highest impact, see guide above)
Improve error messages in
packages/cli/src/core/Add test coverage for security function edge cases
Improve the web dashboard (React 18 + Vite)
Write or improve docs (VitePress)
CONTRIBUTING.md has the full guide.
GitHub: github.com/SubhanshuMG/ForgeKit
npm: npmjs.com/package/forgekit-cli
Website: forgekit.build
Apache 2.0. Built by Subhanshu Mohan Gupta.





