Designing a Personal Knowledge Graph for Software Engineers
Designing a Personal Knowledge Graph for Software Engineers
A personal knowledge graph (PKG) is a structured, queryable representation of your skills, projects, learning goals, and professional relationships. It lets you connect ideas, track progress, and surface relevant information when you need it-whether you’re preparing for a promotion, interviewing, or planning your next learning sprint. This tutorial walks you through building a PKG from scratch, with practical code, tooling choices, and a step-by-step workflow you can adapt.
Why build a PKG
- It surfaces the right context during interviews, performance reviews, and code reviews.
- It helps you identify skill gaps by linking practice problems, projects, and learning resources.
- It makes portfolio updates efficient: your achievements, references, and impact are all linked.
- It lowers cognitive burden: you traverse a consistent graph instead of juggling scattered documents. ### Outline
- Define the PKG domain
- Choose a data model
- Set up storage and a simple API
- Populate your PKG with builder-friendly data
- Build views to consume the PKG
- Maintain and evolve the graph over time ### 1) Define the PKG domain
Start by listing the core entities and relationships you care about. A practical, compact model:
- Person
- properties: name, email, location, titles
- Skill
- properties: name, proficiency (novice to expert), tags
- Project
- properties: name, description, tech_stack, role, outcomes
- relationships: uses Skill, contributed_to
- LearningResource
- properties: title, type (video/article/book), level, link
- relationships: teaches Skill
- Experience
- properties: company, role, start_date, end_date
- relationships: applies Skill
- Goal
- properties: description, target_date, status
- relationships: targets Skill, relates to Project/Experience
Keep it small but extensible. You’ll likely start with a subset and expand.
2) Choose a data model
Two common approaches:
- Linked data style with JSON-LD-like structures
- Pros: human-readable, easy to seed from docs
- Cons: ad-hoc querying can be verbose
- Graph database model (Neo4j, Dgraph, or a light embedded store)
- Pros: powerful traversals, clear relationships
- Cons: more setup, learning curve
For a practical start, a lightweight local graph approach works well. You can start with a JSON-based graph and migrate later.
Data sample (compact skeleton):
{
"people": [
{"id": "me", "name": "Alex Doe", "location": "Carlisle, UK"}
],
"skills": [
{"id": "js", "name": "JavaScript", "proficiency": "advanced"},
{"id": "py", "name": "Python", "proficiency": "intermediate"}
],
"projects": [
{
"id": "proj1",
"name": "Realtime Collaboration Tool",
"description": "Web-based editor with sync",
"tech_stack": ["TypeScript", "React", "WebSocket"],
"roles": ["Frontend Engineer"],
"outcomes": ["Performance improvements", "User growth 25%"]
"uses_skills": ["js", "py"]
}
],
"resources": [
{"id": "r1", "title": "Effective TypeScript", "type": "book", "link": "...", "skill_ids": ["ts"]}
],
"experiences": [ ... ],
"goals": [ ... ]
}
Tip: keep IDs stable and human-readable (slugs or kebab-case).
3) Set up storage and a simple API
Starting point: a small Node.js project with a local JSON store and a REST-ish API.
1) Scaffold
- Create a directory: pkgskg
- Initialize npm, install minimal deps: fs-extra, express, lowdb (a tiny local JSON DB)
Code: setup (run in terminal)
- npm init -y
- npm install express lowdb @types/express typescript ts-node
- Create src/index.ts
2) Basic in-memory Graph API (TypeScript)
// src/index.ts
import express from 'express';
import { Low, JSONFile } from 'lowdb';
type Skill = { id: string; name: string; proficiency?: string };
type Project = { id: string; name: string; tech_stack: string[]; uses_skills?: string[]; description?: string };
type Resource = { id: string; title: string; type: string; link?: string; resource_skills?: string[] };
type DB = {
people: { id: string; name: string; location?: string }[];
skills: Skill[];
projects: Project[];
resources: Resource[];
};
const adapter = new JSONFile('db.json');
const db = new Low(adapter);
async function init() {
await db.read();
db.data ||= { people: [], skills: [], projects: [], resources: [] };
// seed minimal if empty
if (db.data.people.length === 0) {
db.data.people.push({ id: 'me', name: 'Alex Doe', location: 'Carlisle, UK' });
}
await db.write();
}
init();
const app = express();
app.use(express.json());
// Get all skills
app.get('/skills', async (_req, res) => {
await db.read();
res.json(db.data?.skills ?? []);
});
// Add a skill
app.post('/skills', async (req, res) => {
const s = req.body as Skill;
if (!s?.id || !s?.name) return res.status(400).send('Missing id or name');
db.data!.skills.push(s);
await db.write();
res.status(201).json(s);
});
// Basic query: projects by skill
app.get('/projects/by-skill/:skillId', async (req, res) => {
const skillId = req.params.skillId;
await db.read();
const projects = db.data!.projects.filter(p => p.uses_skills?.includes(skillId));
res.json(projects);
});
const PORT = 3000;
app.listen(PORT, () => console.log(PKG API listening on http://localhost:${PORT}));
3) Run
- ts-node or compile to JS with tsc
- Start server: node dist/index.js or ts-node src/index.ts
This gives you a local API to read/write PKG data.
Notes:
- For a longer-term project, switch to a proper DB (SQLite with Prisma, or Neo4j) and implement a graph query layer.
-
Add authentication if you want to keep a private PKG.
4) Populate your PKG with builder-friendly data
Start with your current role: add skills you use daily, e.g., TypeScript, React, Node.js, Testing.
Add key projects: describe the problem, your approach, outcomes, and the skills used.
Link learning resources: a short list of courses or articles that directly improve concrete skills.
Practical tips:
- Use concise, outcome-oriented descriptions: “Reduced API latency by 40% by implementing caching” rather than generic “worked on performance.”
- Capture metrics: lines of code aren’t meaningful; capture user impact, performance, reliability.
- Regularly annotate with date stamps to track progress over time.
Example seed entries:
Skill:
{ id: 'ts', name: 'TypeScript', proficiency: 'advanced' }Project:
{
id: 'proj1',
name: 'Realtime Collaboration Editor',
description: 'A web-based editor with operational transforms for real-time collaboration.',
tech_stack: ['TypeScript', 'React', 'WebSocket'],
uses_skills: ['ts', 'react', 'ws'],
outcomes: ['Reduced merge conflicts', 'Onboarded 3 new features']
}-
Resource:
{ id: 'r12', title: 'Designing Data-Intensive Applications', type: 'book', link: 'https://...', resource_skills: ['ds'] }5) Build views to consume the PKG
You want at least two consumption patterns:
- Personal dashboard
- What you know (skills), what you’ve built (projects), what you’re learning (resources), what you aim for (goals)
- Interview prep view
- Quick index of stories you can tell, mapped to skills and outcomes
Frontend options:
- Static site that reads from your PKG API
- Lightweight React/Vue app that fetches from the local API
- Or export to Markdown/JSON for a resume generator
A simple React example (conceptual):
- Fetch /skills, /projects, /resources
- Display a three-column dashboard:
- Left: Skills with proficiency and recency
- Center: Projects with tech stack and outcomes
- Right: Learning resources and upcoming learning goals
You don’t need to ship a perfect UI; focus on reliable data presentation and searchability.
Search ideas:
- Filter projects by skill
- Filter resources by skill or level
-
Timeline view of goals and experiences
6) Maintain and evolve
Schedule a quarterly PKG review: prune outdated skills, add recent projects, revise goals.
Introduce versioning: commit PKG changes with messages like “feat: add project proj2”
Automate data import: if you maintain public repos, add scripts to extract your contributions and seed the PKG.
Back up data: store db.json in a versioned repo or a cloud backup.
Maintenance checklist:
- Is every project mapped to at least one skill?
- Do goals have updated statuses and dates?
-
Are resources still accessible and relevant?
Example workflow: a 60-minute sprint
10 min: Decide one skill to upgrade this quarter and add a learning resource to it.
20 min: Add a new project entry describing the problem, approach, and outcomes.
10 min: Link the project to the relevant skills.
10 min: Update a goal to reflect progress.
10 min: Run a quick query: which projects used Python? which resources teach React patterns?
This keeps your PKG alive with minimal friction.
Practical example: a small, end-to-end snippet
Suppose you have a PKG with skills and projects. You want to query: “List all projects that used the React skill and show their outcomes.”
Using the simple JSON store approach:
- Projects data includes uses_skills: ['react']
- Query logic (pseudo):
function getProjectsBySkill(skillId) {
return db.projects.filter(p => p.uses_skills?.includes(skillId))
.map(p => ({ name: p.name, outcomes: p.outcomes }));
}
This yields a compact, interview-ready list of impact statements you can cite.
If you migrate to a graph DB later, you can express this as a clear graph traversal, e.g., (p:Project)-[:USES_SKILL]->(s:Skill {id:'react'})
Accessibility and privacy
- If you share your PKG publicly (portfolio), mask sensitive details (contact info, private code paths) and keep public-facing data career-oriented.
-
Use consistent metadata so people (and search engines) can index your PKG effectively.
Next steps
Start small: create a local JSON PKG and a tiny API as shown.
Expand your data model as needed: add more relationships like mentoring or endorsements.
Build at least one public view: a compact resume-like page that highlights your strongest stories.
Illustration idea: Imagine your PKG as a city map. Skills are neighborhoods, projects are buildings, resources are public libraries, and goals are road signs. You navigate by following roads (relationships) that connect your knowledge to concrete outcomes.
Would you like me to tailor this PKG starter to your current stack (e.g., Node.js, React, Python) and provide a ready-to-run project scaffold with TypeScript, Express, and a small React frontend?
-
Rizwan Saleem | https://rizwansaleem.co
Sources
- http://localhost:${PORT}`));
- https://...',
Top comments (0)