Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/DincaAlex/unilink/llms.txt

Use this file to discover all available pages before exploring further.

UniLink is organised as a monorepo with three package.json files. The root package owns no application code — it exists solely to run concurrently, which starts the Express API and the Vite dev server side-by-side with a single command. The server/ directory contains the Node.js backend, and sanmarcos-jobs/ contains the React frontend. There is no Docker, no external database server, and no cloud dependency — everything runs locally out of the box.

Repository structure

unilink/
├── package.json              # root: npm run dev via concurrently
├── server/                   # backend
│   ├── index.js              # Express routes (/api/*)
│   ├── db.js                 # SQLite schema + auto-seed
│   ├── seedData.js           # demo data
│   └── data.sqlite           # generated at runtime
└── sanmarcos-jobs/           # frontend
    ├── index.html
    └── src/
        ├── main.jsx               # app entry point — mounts <AppDataProvider>
        ├── App.jsx                # React Router route definitions
        ├── context/
        │   └── AppDataContext.jsx # global state (jobs, profiles, session)
        ├── lib/
        │   ├── api.js             # fetch-based HTTP client
        │   └── useLocalStorageState.js  # hook for localStorage persistence
        ├── data/
        │   └── mockData.js        # static reference data
        ├── components/            # Navbar, GlowInput, Select
        └── pages/                 # LoginPage, FeedPage, JobDetailPage,
                                   # NewJobPage, ProfilePage, EditProfilePage,
                                   # CvPrintPage

How the two processes communicate

The browser loads the React SPA from the Vite dev server at http://localhost:5173. React components call the functions in src/lib/api.js, which use the browser’s native fetch API to make HTTP requests to the Express API at http://localhost:3001. The backend queries SQLite synchronously via better-sqlite3 and returns JSON. There is no WebSocket layer and no server-side rendering.

Ports and start commands

ProcessPortStart command
Express API3001npm run dev --prefix server
Vite frontend5173npm run dev --prefix sanmarcos-jobs
Both togethernpm run dev (root)
The root npm run dev script passes concurrently the prefixed commands with colour-coded labels (backend in blue, frontend in green) so their log output is easy to tell apart in one terminal.

CORS

The Express server configures the cors middleware to allow requests from http://localhost:5173 only:
server/index.js
app.use(cors({ origin: 'http://localhost:5173' }))
Any request from a different origin — including a production URL — will be rejected by the browser’s CORS policy without reaching any route handler.

Tech stack

LayerTechnology
Frontend frameworkReact 18 + Vite 5
StylingTailwind CSS 3
RoutingReact Router 6
IconsLucide React
Global stateContext API + useState
BackendNode.js 20 + Express 4
DatabaseSQLite via better-sqlite3
Orchestrationconcurrently
Node.js 20 is required. Vite 5 is pinned (not 6+) because Vite 6 requires Node 20.19+, which is newer than the 20.17 version used during development. Tailwind CSS 3 is used (not v4) because Tailwind v4’s @tailwindcss/vite plugin is incompatible with the current Node version.

Build docs developers (and LLMs) love