Packages and Scripts for a Two-Part App
Clone Sprout and you find two folders, client and server, each with its own package.json. Those two small files say what each half needs and how to start it. Read them well and you can run either half with one command, and keep code meant for the browser apart from code meant for the server.
The rule
Each half has its own package.json: what it needs, and how to run it.
sprout/
client/ React app that runs in the browser
package.json
src/
server/ Node.js API that runs on the server
package.json
src/
.gitignoreHere is the server's file:
{
"name": "sprout-server",
"type": "module",
"scripts": {
"dev": "node --watch src/index.js",
"start": "node src/index.js",
"test": "node --test"
},
"dependencies": {
"express": "^4.19.2",
"pg": "^8.12.0"
},
"devDependencies": {
"eslint": "^9.9.0"
}
}dependenciesare packages the running app imports: Express and the PostgreSQL driverpgon the server, React in the client.devDependenciesonly help while you write, test or build: linters, test tools, and the client's build tool, Vite.scriptsare named commands.npm run devstarts either half in development;npm startandnpm testwork without the wordrun.package-lock.jsonrecords the exact version of every installed package. Commit it, so every laptop and the build server install the same tree.npm ciinstalls exactly what it says.node_modules/is rebuilt from the lockfile, so it is never committed; it belongs in.gitignore.
The two halves also end up very differently. The server runs as a long-lived process with npm start. The client runs npm run build, which turns the React source into plain HTML, CSS and JavaScript files in client/dist/. In production nothing "runs" the client at all; a web server simply hands those files to browsers.
Separate lists make it obvious what runs where. The browser build never needs the database driver, and the API never needs React. (Tools such as npm workspaces can manage both folders from the root, but each half still keeps its own list.)
The shortcut
For every package, ask two questions. Which half imports it? That picks the folder. Does the running app import it, or only my tools? That picks dependencies or devDependencies.
pg
The server's code imports it at runtime to talk to PostgreSQL.
server, dependencies.
The trap is installing pg in the client folder "because the client needs data". The client never talks to the database. It asks the API.
Drills
Answer fast — trust the rule.
Sprout's server imports express when it runs. Where does it belong?
Which of these should be committed to git?
What does npm run build produce for Sprout's React client?
The build server must install exactly the versions the team tested. Which command fits?
Remember
- Each half has its own package.json: what it needs, and how to run it.
- Shortcut: which half imports it, and does the running app import it or only your tools?
- Trap: database packages in the client. The browser asks the API; only the server talks to the database.
