A genuinely running full-stack JavaScript application — an independent, from-scratch implementation of the core of Full Stack Open (University of Helsinki), part of a csdiy.wiki full-catalog build.
Full Stack Open is Helsinki's deep-dive into modern web development (React, Node/Express, MongoDB, testing, GraphQL, TypeScript, CI/CD). This repository implements a coherent end-to-end through-line across the course's core, testable parts, built around the two signature course applications:
- Bloglist — a full-stack single-page app: an Express REST API with
Mongoose, JWT authentication and bcrypt (parts 3–4), and a React SPA with
React Query, React Router, custom hooks and Context/
useReducer(parts 5–7). - Library — a GraphQL API built with Apollo Server v4, Mongoose and JWT auth (part 8).
Everything runs and is tested for real on a CPU-only Windows machine. The test
suites use an in-memory MongoDB (mongodb-memory-server) so nothing external
needs to be installed to reproduce every number below.
| Component | What it is | Result (measured) |
|---|---|---|
| Backend REST API (parts 3–4) | Express + Mongoose + JWT Bloglist API | 31/31 Jest + Supertest tests pass; live smoke: 11/11 HTTP checks |
| Frontend SPA (parts 5 & 7) | React + React Query + Router Bloglist client | 8/8 Vitest + RTL tests pass; vite build = 145 modules, 261.88 kB (gzip 86.52 kB) |
| Library GraphQL API (part 8) | Apollo Server v4 + Mongoose + JWT | 13/13 Jest tests pass; live smoke: 9/9 GraphQL checks |
| Total | 52/52 automated tests, 20/20 live E2E checks, 0 failures |
Raw evidence is in results/: backend_tests.txt,
frontend_tests.txt, graphql_tests.txt, frontend_build.txt,
backend_smoke.txt, graphql_smoke.txt, and SUMMARY.txt.
Example — the backend live smoke transcript (results/backend_smoke.txt):
=== Full Stack Open Bloglist API — live smoke test ===
[PASS] GET /health returns 200 "ok"
[PASS] POST /api/users creates a user (201) -> id=6a4effb3315f238f0fdec99d
[PASS] password hash is not leaked
[PASS] POST /api/login returns a JWT (200)
[PASS] POST /api/blogs without token is rejected (401)
[PASS] POST /api/blogs with token creates a blog (201) -> title="Full Stack Open is great"
[PASS] created blog is linked to its owner
[PASS] PUT /api/blogs/:id updates likes -> likes=43
[PASS] GET /api/blogs returns the blog with populated user -> count=1
[PASS] DELETE /api/blogs/:id by owner succeeds (204)
[PASS] blog list is empty after deletion -> count=0
=== smoke result: 11 checks passed, 0 failed ===
- Part 3 — Node/Express server: REST API, layered structure
(
app.js/index.js, controllers, models, middleware), Mongoose models, proper error-handling middleware. - Part 4 — Testing & user administration:
list_helperexercises, Jest + Supertest integration tests, users with bcrypt-hashed passwords, token-based (JWT) authentication, owner-only blog deletion. - Part 5 — Testing React apps: login flow with
localStoragetoken persistence,TogglableviaforwardRef/useImperativeHandle, Vitest + React Testing Library component tests (the canonicalBlog/BlogFormtests). - Part 6 — Advanced state management: React Query for server state
(queries + mutations + cache invalidation), notification and user state via
useReducer+ Context. - Part 7 — Custom hooks & routing: React Router views
(
/,/blogs/:id,/users,/users/:id), theuseFieldcustom hook. - Part 8 — GraphQL: Apollo Server v4 schema & resolvers, filtered
queries, authenticated mutations, JWT context, tested via
server.executeOperation.
Parts 0–2 (fundamentals, intro React, talking to the server) are the foundations these apps build on; parts 9–13 (TypeScript, React Native, CI/CD, containers, relational DBs) are out of scope for this deliverable and are noted here for completeness.
full-stack-open/
├── backend/ # parts 3–4 — Bloglist REST API (Express + Mongoose + JWT)
│ ├── app.js index.js
│ ├── controllers/ # blogs, users, login
│ ├── models/ # blog, user
│ ├── utils/ # config, db, logger, middleware, list_helper
│ ├── scripts/smoke.js
│ └── tests/ # Jest + Supertest (mongodb-memory-server)
├── frontend/ # parts 5 & 7 — Bloglist React SPA (Vite)
│ └── src/
│ ├── components/ # Blog, BlogForm, Togglable, Login, Menu, Users, ... + *.test.jsx
│ ├── contexts/ # NotificationContext, UserContext (useReducer)
│ ├── hooks/ # useField (+ test)
│ ├── services/ # axios: blogs, login, users
│ └── App.jsx main.jsx
├── graphql/ # part 8 — Library GraphQL API (Apollo Server v4)
│ ├── schema.js resolvers.js server.js index.js
│ ├── models/ # author, book, user
│ ├── scripts/smoke.js
│ └── tests/ # Jest via executeOperation
└── results/ # captured test / build / smoke evidence
Prerequisites: Node.js 18+ (developed on v22). Tests need no external
MongoDB — mongodb-memory-server downloads/uses a local mongod binary.
# ---- Backend (parts 3–4) ----
cd backend
npm install
npm test # 31 Jest + Supertest tests on in-memory MongoDB
npm run smoke # boots the real server, exercises the live HTTP API
# real deployment: set MONGODB_URI + SECRET (see .env.example) then `npm start`
# ---- Frontend (parts 5 & 7) ----
cd ../frontend
npm install
npm test # 8 Vitest + React Testing Library tests
npm run build # production build -> dist/
npm run dev # dev server on :5173, proxies /api -> backend :3003
# ---- Library GraphQL (part 8) ----
cd ../graphql
npm install
npm test # 13 Jest tests via Apollo executeOperation
npm run smoke # boots the real Apollo HTTP server, runs live GraphQL ops- Backend:
npm test→Tests: 31 passed, 31 total(results/backend_tests.txt).npm run smokeboots the Express app against an in-memory Mongo and drives every route over HTTP with real JWTs — 11/11 checks (results/backend_smoke.txt). - Frontend:
npm test→Tests 8 passed (8)(results/frontend_tests.txt);npm run buildtransforms 145 modules (results/frontend_build.txt). - GraphQL:
npm test→Tests: 13 passed, 13 total(results/graphql_tests.txt);npm run smokeruns 9/9 live GraphQL operations against the standalone Apollo server (results/graphql_smoke.txt).
- Backend: Node.js, Express 4, Mongoose 8, jsonwebtoken, bcryptjs, express-async-errors; Jest 29, Supertest, mongodb-memory-server.
- Frontend: React 18, Vite 6, React Router 6, TanStack React Query 5, Axios; Vitest 2, React Testing Library, jsdom.
- GraphQL: Apollo Server 4, GraphQL 16, Mongoose 8, jsonwebtoken, bcryptjs; Jest 29, mongodb-memory-server.
- Structuring an Express app for testability (separating
appfrom the HTTP listener and the DB connection) so Supertest can exercise routes in-process. - Token-based authentication end-to-end: bcrypt password hashing, JWT signing,
a
userExtractormiddleware, and owner-only authorization on delete. - Integration testing against a real (in-memory) MongoDB instead of mocks — genuine Mongoose queries, populated relations, unique-index violations.
- Server-state management with React Query (queries, mutations, cache
invalidation) kept distinct from UI state handled by
useReducer+ Context. - Reusable React patterns:
forwardRef/useImperativeHandlefor imperative child control, and custom hooks (useField) for controlled inputs. - Designing a GraphQL schema with field resolvers (
Author.bookCount), argument-filtered queries, and auth enforced through the Apollo context.
Based on the assignments of Full Stack Open by the University of Helsinki (Department of Computer Science) and Houston Inc. This repository is an independent educational reimplementation; all course materials and specifications belong to their original authors. See the course at https://fullstackopen.com/en/. Original code in this repository is released under the MIT License.