DEV Community

Cover image for I Built My Friend Kritika a Project Mentor That Runs on Local Gemma
Swayam Takkamore
Swayam Takkamore

Posted on

I Built My Friend Kritika a Project Mentor That Runs on Local Gemma

Hacktoberfest Weekend Challenge: Build for a Friend Submission ๐Ÿค

This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend


๐Ÿชง The Line Nobody Warns You About

You know the one. It shows up on basically every job post:

"Experience with real-world projects required."

I'm a student too, so I've seen it from the inside. You can ace every exam and still have nothing to point at. Tutorials end the second the video does. Real work is messier: there are tasks, blockers, deadlines, and (if you're lucky) someone you can ask when you're stuck.

That gap is what SkillPilot is about. And I built it for my friend Kritika.


The Short Version

Built for My friend Kritika
The problem Students have grades but nothing that looks like real project experience
What it is An AI-powered learning platform that simulates real industry workflows
The open-source bit Gemma, an open-weight model, running locally in my backend
Built with Next.js 14 ยท Express + TypeScript ยท Flutter ยท MongoDB Atlas

So What Does It Actually Do?

If you're a student, it works like a tiny, friendly workplace:

  1. Tell it what you're into and how comfortable you are. It hands you a real-feeling project: a title, a description, a difficulty level, a suggested tech stack, 5โ€“8 concrete tasks and a deadline.
  2. Work the board. Tasks live on a Kanban board (To Do, In Progress, Done), and your progress updates automatically as you move cards across.
  3. Ask the mentor when you're stuck. It's an AI chat that knows which project you're in, so you get help with your thing, not a generic answer.
  4. Finish and show it off. When the project's done, SkillPilot writes a portfolio entry, a skills summary and resume-ready bullet points. You get a public page at /portfolio/[username].

If you're a recruiter, you can browse and filter student profiles, open the projects and technologies behind them, and run an AI skill analysis that breaks a student's abilities down by category.

And every bit of AI in there runs on Gemma, locally in my backend. No closed API anywhere.


Poke Around the Repo

It's a monorepo. This is what the web/ side looks like when I ls around:

SkillPilot/web$ ls
backend  frontend

SkillPilot/web/frontend$ ls
next.config.js  next-env.d.ts  package.json  package-lock.json  postcss.config.js  src  tailwind.config.ts  tsconfig.json

SkillPilot/web/backend$ ls
node_modules  package.json  package-lock.json  src  tsconfig.json
Enter fullscreen mode Exit fullscreen mode

There's also a mobile/ Flutter app and a docs/ folder (architecture, setup, API notes) at the repo root.

A quick honesty note: SkillPilot has a bit of a backstory. It began as a prototype for the TechmentorX Hackathon. What I'm writing about here is the current version, where the AI layer runs on open-weight Gemma locally in the backend.


How It's Put Together

 Next.js 16 (web)  โ”€โ”€โ”€โ”
                      โ”œโ”€โ”€โ–บ  Express + TypeScript API  โ”€โ”€โ–บ  AI service layer  โ”€โ”€โ–บ  Local Gemma
 Flutter (mobile)  โ”€โ”€โ”€โ”˜              โ”‚
                                     โ””โ”€โ”€โ–บ  MongoDB Atlas
Enter fullscreen mode Exit fullscreen mode

The AI calls live in their own service layer in the backend, separate from the route controllers. Controllers just ask it for a project, a mentor reply, a portfolio or a skill score.

The stack

Layer What I used Why
Web Next.js 14, TypeScript, Tailwind, Zustand, Framer Motion Quick dashboards, a public portfolio route, simple state
API Node.js, Express, TypeScript, Mongoose Typed all the way through, fast to iterate on
Mobile Flutter, Provider, Material 3 One codebase, and students live on their phones
Database MongoDB Atlas Projects, tasks, chats and portfolios are all document-shaped
Auth JWT access + refresh tokens, bcrypt, httpOnly cookies Boring, safe defaults
AI Gemma (open-weight), run locally Open weights I control, and no per-request cost

The API

Method Endpoint What it does
POST /api/auth/signup ยท /api/auth/login Accounts
POST /api/projects/generate AI-generated project
PATCH /api/tasks/:projectId/:taskId/status Move a Kanban card
POST /api/chat/:projectId Project-scoped mentor chat
POST /api/projects/:id/portfolio Portfolio and resume bullets
GET /api/recruiter/students Browse talent
POST /api/recruiter/students/:id/skill-score AI skill analysis

How Gemma pulls its weight

Project generation is a contract, not a chat. The Kanban board has to render whatever the AI sends back, so the output has to follow a shape (simplified):

{
  "title": "string",
  "description": "string",
  "difficulty": "beginner | intermediate | advanced",
  "techStack": ["string"],
  "tasks": [{ "title": "string", "description": "string" }],
  "deadline": "ISO date"
}
Enter fullscreen mode Exit fullscreen mode

The mentor knows where you are. POST /api/chat/:projectId ties every conversation to one project, so answers are about what you're actually building.

Portfolios write themselves. When a project is finished, the AI looks at the project and its tasks and turns them into a summary, the skills you picked up, and resume bullets.

Skill scores are a starting point, not a verdict. Scoring a person is the most sensitive thing SkillPilot does. The score is there to help a recruiter dig into a student's real projects, not to replace looking at them.


Want to Run It?

# Backend
cd web/backend
cp .env.example .env     # add your credentials
npm install
npm run dev              # http://localhost:5000

# Frontend
cd web/frontend
cp .env.example .env.local
npm install
npm run dev              # http://localhost:3000

# Mobile
cd mobile
flutter pub get
flutter run
Enter fullscreen mode Exit fullscreen mode

More detailed setup lives in docs/setup.md.


Why Open (and Local) Matters Here

The challenge asks where going open actually beats going closed. For SkillPilot, it's these five things.

1. The AI lives on my backend, not someone else's.
People think twice about sharing unfinished project ideas, "why doesn't my code work?" questions, and skill scores with their name on them. With Gemma, inference happens on hardware I control, so those prompts and answers don't get sent to a third-party model API. To be precise, the app's data is stored in MongoDB Atlas. Local Gemma keeps the model side in my hands, and I'd rather claim exactly that.

2. Students can't pay per token.
A mentor is only useful if you can ask the hundredth question without watching a meter. Local inference means no per-request cost and no model API key to rotate or leak. It doesn't get pricier when more students show up.

3. The model isn't wired into everything.
Since the AI calls sit in one service layer, upgrading or swapping the model stays contained to one place. I'm not at the mercy of one vendor's pricing, deprecations or surprise model updates.

4. Scoring people deserves something you can inspect.
A system that evaluates students for recruiters should sit on something you can examine and test. Open weights let me poke at how the scorer behaves instead of treating it as a black box.

5. The honest trade-off.
A local open model is smaller than the biggest hosted ones. I'm fine with that for a product aimed at students: cheaper, more private on the model side, and fully in my control.

Closed API Local Gemma (SkillPilot)
Prompts leave my backend Yes No
Cost per request Per token None
Swap or upgrade the model Vendor decides I decide
Needs a model API key Yes No
Raw capability ceiling Higher Lower

Where I'd Take It Next

  • Get SkillPilot in front of more students and fix whatever confuses them.
  • Show recruiters why a skill score came out the way it did.
  • Try other open models behind the same AI service layer.

Prize Categories

  • Best Use of Gemma: Gemma, an open-weight model run locally in my backend, powers every AI feature: project generation, the project-scoped mentor, portfolio writing and skill scoring.
  • Best Use of MongoDB Atlas: Atlas is the data layer behind an app built on an open-weight model. It stores users, projects, task state, chat history and portfolios.

Before You Go

Building for one person is a good constraint. Every feature has to earn its place by being useful to someone real, and for SkillPilot that someone is Kritika.

If you've mentored a junior, or you were the student with the empty portfolio, I'd love to hear what finally got you from "I've learned things" to "I've built something." Tell me in the comments. ๐Ÿ‘‡

Did this project with my friend as a teammate - @aniket937

Top comments (0)