Contributing Guide
Help build EngPath
You don't need to know React. Every contribution area is a TypeScript data file — add a roadmap domain, write a mindset article, or list an open source project.
Quick Start
Three steps to your first PR
Fork the repository
Fork citraFebriawirti/EngPath on GitHub, clone it locally, and create a new branch from main.
Pick what to add
Choose a contribution area below. Each area is a TypeScript data file — no component work required.
Open a pull request
Push your branch and open a PR against main. Keep PRs focused — one contribution area per PR.
Choose Your Path
Pick a contribution area
Each area has step-by-step instructions below. Click a card to jump directly to its guide.
Roadmap Domain
Add a new career domain
A roadmap domain is a TypeScript object that describes a career path: its metadata, color, and an array of skill nodes. Once you create the file and register it in the index, it automatically appears on the roadmap listing page.
Create the domain file
Create a new folder under src/content/roadmap/ and add an index.ts file following the RoadmapDomain type.
// src/content/roadmap/your-domain/index.ts
import type { RoadmapDomain } from "@/content/roadmap/types";
export const yourDomain: RoadmapDomain = {
slug: "your-domain",
label: "Your Domain",
flag: "Specialization", // "Core" | "Specialization" | "Domain"
shortDesc: "Short description shown on roadmap cards.",
longDesc: "Longer description displayed on the domain page.",
color: "#F59E0B",
bg: "rgba(245,158,11,0.10)",
meta: { nodes: 0, hours: 0 }, // update after adding nodes
nodes: [
{
id: "yd-first-skill", // prefix id with your domain abbreviation
title: "Your First Skill",
type: "core", // "core" | "optional"
level: 1, // 1=Foundation 2=Intermediate 3=Advanced 4=Expert
description: "What this skill covers and why it matters.",
tags: ["tag1", "tag2"],
resources: [
{ label: "Resource Name", href: "https://example.com" },
],
},
],
};Register the domain
Open src/content/roadmap/index.ts and add your domain to the imports and the roadmapDomains array. That's it — the page renders automatically.
// src/content/roadmap/index.ts — two changes required
// 1. Add the import (alphabetical order preferred)
import { yourDomain } from "./your-domain";
// 2. Add to the domains array
export const roadmapDomains: RoadmapDomain[] = [
backend, frontend, devops, mobile, security,
data, qa, dba, business,
yourDomain, // ← add here
];Mindset Article
Write a mindset article
Articles are written with a structured block format — no MDX, no markdown files, just TypeScript. Each block is typed so you always know exactly what fields are required. Three registrations are needed across two files.
Create the article content file
Create src/content/mindset/your-article/index.ts and fill in the MindsetArticleContent shape. Available block kinds: p, h2, h3, callout, list, quote, code, conversation, takeaways, refs.
// src/content/mindset/your-article/index.ts
import type { MindsetArticleContent } from "@/content/mindset";
export const yourArticle: MindsetArticleContent = {
slug: "your-article", // must match folder name
title: "Your Article Title",
excerpt: "One-sentence summary shown on listing cards.",
category: "Thinking Models", // use existing or add a new one
readMin: 7,
color: "#4F8EF7",
bg: "rgba(79,142,247,0.10)",
featured: false, // set true to highlight on the listing page
iconName: "Target", // any valid Lucide icon name
lead: "Opening paragraph shown at the top of the article.",
blocks: [
{ kind: "h2", text: "First Section Heading" },
{ kind: "p", text: "Paragraph text here." },
{
kind: "callout",
variant: "insight", // "insight" | "warning" | "tip"
title: "Key Insight",
body: "Callout body text.",
},
{ kind: "list", style: "bullet", items: ["Item 1", "Item 2"] },
{ kind: "takeaways", items: ["Main takeaway 1", "Main takeaway 2"] },
],
};Register in the content index
Import your article in src/content/mindset/index.ts and add it to the internal articles array. This is what the slug-based article page uses to resolve content.
// src/content/mindset/index.ts — add import + register
// 1. Add the import
import { yourArticle } from "./your-article";
// 2. Add to the articles array
const articles: MindsetArticleContent[] = [
firstPrinciplesArticle,
systemsThinkingArticle,
// ... existing articles ...
yourArticle, // ← add here
];Add display metadata for the listing page
Add a lightweight entry to the articles array in src/app/mindset/data.ts. This drives the card grid on the mindset listing page.
// src/app/mindset/data.ts — add display metadata
export const articles: MindsetArticle[] = [
// ... existing entries ...
{
slug: "your-article", // must match content file slug
title: "Your Article Title",
excerpt: "One-sentence summary.",
category: "Thinking Models",
readMin: 7,
iconName: "Target",
color: "#4F8EF7",
bg: "rgba(79,142,247,0.10)",
featured: false,
},
];Open Source Project
List an open source project
The simplest contribution — add one object to a single array. The project will appear on the open source page, sorted and filtered by difficulty automatically.
Add the project to the data array
Open src/app/opensource/data.ts and append an object to the projects array. The difficulty level controls which section it appears in on the page.
// src/app/opensource/data.ts — add to the projects array
export const projects: OsProject[] = [
// ... existing projects ...
{
name: "your-project",
fullName: "Your Project Full Name",
description: "One to two sentences describing what the project does.",
stars: 0,
forks: 0,
lang: "TypeScript",
langColor: "#3178C6",
difficulty: "Beginner", // "Beginner" | "Intermediate" | "Advanced"
category: "Tooling", // e.g. "API", "CLI", "UI", "Data", "Tooling"
tags: ["tag1", "tag2"],
// href: "/opensource/your-project", // optional: internal detail page
// githubUrl: "https://github.com/org/repo", // optional: external GitHub
},
];Tip
The href field links to an internal detail page (/opensource/[slug]), while githubUrl links directly to the GitHub repository. Both are optional — you can provide one, both, or neither and only include the card metadata.
Before You Submit
PR guidelines
Run through this checklist before opening your pull request to keep the review process fast.
Build passes
Run npm run build locally — zero TypeScript errors before opening a PR.
One area per PR
Don't mix roadmap + article changes in the same PR. Keep scope small and reviewable.
Follow naming conventions
Use kebab-case for all folder and file names (e.g. my-new-article/index.ts).
Fill all required fields
Every field in the TypeScript type is required unless explicitly marked optional.
At least one resource per node
Each roadmap skill node should link to at least one learning resource.
Article length
Aim for 6–12 minute reads. Use blocks: h2, p, callout, list, takeaways.
Get Started
Ready to open your first PR?
Fork the repo, pick an area above, and open a pull request. The maintainers are friendly and will help you get merged.