Hello! Welcome back to our course on developing a modern JavaScript framework.
In our previous lesson, we customized our biome.json file, defining a consistent set of formatting and linting rules for our project. This gave us a "single source of truth" for code quality.
Today, we'll focus on integrating these rules directly into our development workflow to ensure they are applied automatically and consistently. This lesson is about moving from a defined standard to an enforced one. As a lead developer, you know that the value of a linter or formatter lies in its consistent application, and automation is the key to achieving that across a team.
By the end of this lesson, you will be able to integrate BiomeJS with VS Code for real-time feedback and set up pre-commit hooks to safeguard your codebase.
1. Real-Time Feedback in VS Code
The fastest feedback loop is one that happens as you type. By integrating Biome directly into your code editor, you get immediate visual cues for errors and can automatically format your code every time you save.
Step 1: Install the Biome VS Code Extension
First, you need to install the official Biome extension. This allows VS Code to communicate with the Biome toolchain.
- Open VS Code.
- Go to the Extensions view (Ctrl+Shift+X).
- Search for "Biome" (make sure it's the one published by Biome).
- Click "Install".
Step 2: Configure Your Workspace
To ensure that anyone who works on this project has the same editor behavior, we will add settings directly to the project. This is done by creating a .vscode/settings.json file. These settings will override global user settings but only for this workspace.
The following video demonstrates installing the extension and creating the settings.json file.
Lint & Format JavaScript with Biome
Watch this segment from Colby Fayock's video, "Lint & Format JavaScript with Biome", to see how to install the extension and configure VS Code to use Biome for formatting.
Watch from 05:48 to 07:39. The video will walk you through finding and installing the extension, then creating a .vscode/settings.json file and adding the configuration to set Biome as the default formatter for JavaScript and TypeScript files.
Based on the video, create a new folder named .vscode in the root of your project. Inside it, create a file named settings.json and add the following configuration:
{
"[javascript][typescript][javascriptreact][typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
}
}
This tells VS Code to use the Biome extension as the default formatter for all relevant file types.
Step 3: Enable Format on Save
The real power comes from automatically applying formatting every time you save a file. This eliminates the manual step of running a format command.
Lint & Format JavaScript with Biome
This next clip from the same video shows how to enable format on save and also how to enable Biome's 'quick fix' actions.
Watch from 08:02 to 08:59. Focus on the two settings being added: editor.formatOnSave and editor.codeActionsOnSave.
Let's update your .vscode/settings.json to include these settings. Your final file should look like this:
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit"
},
"[javascript][typescript][javascriptreact][typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
}
}
"editor.formatOnSave": true: This is the key setting that triggers formatting when you save."quickfix.biome": "explicit": This enables Biome to apply its "safe" fixes (like changingvartoconst) automatically on save.
Test it out: Open your src/index.ts file, add some extra spaces or change single quotes to double quotes, and hit save. The code should instantly snap back to the style you defined in biome.json.
2. Enforcing Quality with Pre-Commit Hooks
Editor integration is great for you, but you can't guarantee that every contributor will have the same setup. A pre-commit hook acts as a safety net, running checks on your code before it's committed to version control. This ensures that no non-compliant code ever enters your repository.
We will use two popular tools for this:
- Husky: A tool that makes it easy to manage Git hooks.
- lint-staged: A tool that runs commands only on the files that are staged for the current commit. This is crucial for performance, as it avoids linting the entire project on every commit.
The official Biome documentation provides excellent recipes for this.
First, let's review the official Biome documentation on Git hooks. This will give you a solid conceptual understanding of the tools we're about to use.
Read the introduction and the "Husky" section. Pay attention to how Husky and lint-staged work together and see the example configuration for package.json.
Now, let's follow a practical guide to get this set up.
Lint & Format JavaScript with Biome
This extended clip from Colby Fayock's video provides a detailed, step-by-step walkthrough of installing and configuring both Husky and lint-staged to work with Biome.
Watch from 17:06 to 22:53. Follow along with the video to perform the installation and configuration steps in your own project. The video clearly explains why running scripts only on staged files is the preferred approach.
Let's walk through the steps together, combining the insights from the video and the official documentation.
Step 1: Install Dependencies
In your terminal, install husky and lint-staged as development dependencies:
npm install --save-dev husky lint-staged
Step 2: Initialize Husky
Run the Husky initialization command. This will create a .husky directory in your project.
npx husky init
After running this, you'll see a new file: .husky/pre-commit. By default, it might contain a command like npm test. We're going to change that.
Step 3: Configure lint-staged and Connect to Husky
First, modify the .husky/pre-commit file to run lint-staged:
# .husky/pre-commit
npx lint-staged
Next, add the lint-staged configuration to your package.json. This tells lint-staged what command to run on which files. We'll use the command recommended by the Biome documentation.
Add this block to your package.json:
// package.json
{
// ... other properties like name, version, scripts
"lint-staged": {
"*.{js,ts,cjs,mjs,jsx,tsx,json,jsonc}": [
"biome check --write --no-errors-on-unmatched"
]
}
}
- The glob pattern
*.{js,ts,...}selects all relevant files that are currently staged. biome check --write: This single command both formats and applies safe lint fixes.--no-errors-on-unmatched: This is an important flag that preventslint-stagedfrom throwing an error if a commit contains no files matching the glob pattern (e.g., you only changed a Markdown file).
Step 4: Test the Pre-Commit Hook
To ensure the hook is working independently of your editor settings, let's test it:
- Temporarily disable "format on save" in your
.vscode/settings.jsonby setting it tofalse. - Open
src/index.tsand mess up the formatting again (e.g., add extra lines, use double quotes). Save the file. - Stage the file:
git add src/index.ts. - Try to commit it:
git commit -m "feat: add messy code".
You will see output in your terminal from lint-staged and Biome. The command will run, fix the file, and then the commit will complete successfully. If you check src/index.ts now, you'll see it's been formatted. The code committed to your history is the clean version.
Remember to re-enable "format on save" in your settings file!
Conclusion
Congratulations! You have now fully automated your code quality workflow.
Key Takeaways:
- Editor Integration: The Biome VS Code extension, combined with project-specific settings in
.vscode/settings.json, provides an immediate feedback loop with formatting and fixing on save. - Repository-Level Enforcement: Pre-commit hooks act as a crucial quality gate for your entire team.
- Efficient Tooling: The combination of
husky(to manage hooks) andlint-staged(to operate only on staged files) is a powerful and efficient industry-standard pattern for this task.
Next Lesson Preview:
With our development environment and quality tooling fully configured, we can now turn our attention to the heart of our library: the TypeScript configuration. In the next lesson, we will configure tsconfig.json for strict library type checking and declaration file generation, ensuring our framework is robust, type-safe, and ready for others to consume.
Can't find a good explanation? Sign up and we'll make it for you
Sign up