Full-project lesson · needs Node.js, npm and real project files, so it does not run in the in-page playground.
package.json is the identity card of your project. It says what the project is, which packages it needs and which commands you can run. This is the file created by the Vite React template (create-vite 9):
{
"name": "myapp",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "oxlint",
"preview": "vite preview"
},
"dependencies": {
"react": "^19.2.8",
"react-dom": "^19.2.8"
},
"devDependencies": {
"@types/react": "^19.2.18",
"@types/react-dom": "^19.2.7",
"@vitejs/plugin-react": "^6.1.1",
"oxlint": "^1.81.0",
"vite": "^8.3.0"
}
}
The fields
name,version: the project’s name and version. Only matter if you publish it.private: true: stops you from publishing it to npm by accident."type": "module": tells Node to treat.jsfiles as modern ES modules, so you can useimportandexportin config files.scripts: commands you run withnpm run <name>.dependencies: packages your app needs at run time. React and React DOM are here.devDependencies: packages needed only while building: Vite, the React plugin, the linter and type definitions.
The scripts
| Script | Command | Use |
|---|---|---|
dev | vite | Start the development server |
build | vite build | Create the production build in dist |
lint | oxlint | Check the code for mistakes |
preview | vite preview | Serve the built dist folder locally |
npm run dev runs the dev script, and so on. (npm start and npm test are special names that work without run.) You can add your own scripts, for example "test": "vitest" in Basic Testing Concepts.
Version ranges
"react": "^19.2.8" means “version 19.2.8 or any newer version that is still 19.x”. The ^ allows minor and patch updates, but not 20.0.0. That is why a new project today installs React 19.3.0 even though the template says 19.2.8. The exact versions that were installed are written in package-lock.json.
The lock file
package-lock.json records the exact version of every package, including the packages your packages use. Commit it to Git. It makes sure everybody on the team, and your build server, gets the same versions.
Adding and removing packages
npm install react-router
npm install --save-dev vitest
npm uninstall react-router
The first adds to dependencies. --save-dev (or -D) adds to devDependencies. Use dependencies for code that ends up in the browser and devDependencies for tools. Bundlers include only what you import, so for a client-side app the difference is mostly about clarity.
Never edit node_modules
node_modules is generated. If something looks broken, delete the folder and run npm install again. Put your changes in your own files.Key points
scriptsdefine the commands;dependenciesanddevDependencieslist packages.^accepts compatible newer versions; the lock file pins exact ones.- Add packages with
npm installand commitpackage.jsonandpackage-lock.json.