Unlock Project-Wide JSDoc in VSCode: The #1 Fix for 2025
Tired of adding `// @ts-check` to every file? Learn the #1 fix to enable project-wide JSDoc type checking in VSCode for ultimate productivity in 2025.
Alex Miller
A senior front-end developer passionate about tooling, DX, and scalable JavaScript architectures.
You’ve done the right thing. You’ve meticulously documented your JavaScript functions with JSDoc, adding @param
, @returns
, and even custom @typedef
types. You open a file, and VSCode’s IntelliSense is magical—autocompleting properties, catching type errors, and making you feel like a programming superhero. But then you import that beautifully documented module into another file, and... nothing. Silence. The magic is gone. VSCode is suddenly oblivious to all your hard work.
If this sounds painfully familiar, you're not alone. This is one of the most common frustrations for developers who embrace JSDoc for type-safe JavaScript. For years, the common advice was to litter your project with comments, but there’s a much cleaner, more powerful way. This is the definitive, project-wide fix you need for 2025.
The Frustration: Why Isn't JSDoc Working Everywhere?
The magic behind VSCode's JavaScript IntelliSense is actually the TypeScript language server working in the background. It's incredibly powerful and can infer a lot about your code. However, for performance reasons, its default behavior in a standard JavaScript project is conservative. It analyzes your currently open files and their direct dependencies, but it doesn't proactively scan your entire project to build a complete type graph.
This is why JSDoc comments in utils.js
might not provide any IntelliSense in main.js
unless you have both files open and have recently interacted with them. The editor simply doesn't know it's supposed to treat your entire folder as a single, cohesive project. To unlock that power, you need to give it a hint. A very specific, very powerful hint.
The Old Way: The Tedium of // @ts-check
For a long time, the most common solution you'd find on Stack Overflow was to add a simple comment to the top of every single JavaScript file you wanted to be type-checked:
// @ts-check
import { calculateTotal } from './utils.js';
// Now VSCode will check this file!
const result = calculateTotal('a string', 10); // 😱 Error! Argument of type 'string' is not assignable to parameter of type 'number'.
This works, but it's a manual, brittle solution. It suffers from several major drawbacks:
- Tedious: Adding it to dozens or hundreds of files is a pain.
- Error-Prone: It's easy to forget to add it to a new file, creating inconsistent type-checking coverage.
- Not Truly Project-Wide: It enables checking on a per-file basis, but it doesn't fundamentally tell VSCode to treat the whole directory as a unified project.
It's a band-aid, not a cure. Luckily, the cure is simple.
The #1 Fix: Unleashing Project-Wide Power with jsconfig.json
The single most effective way to enable project-wide JSDoc analysis in VSCode is to create a jsconfig.json
file in the root of your project. The mere presence of this file signals to VSCode that your directory of loose .js
files is, in fact, a formal project.
Your Step-by-Step Guide to JSDoc Nirvana
- Create the File: In the root directory of your project (the same level as your
package.json
andnode_modules
), create a new file namedjsconfig.json
. -
Add the Magic Configuration: Copy and paste the following configuration into your new file. This is a fantastic starting point for most modern JavaScript projects.
{ "compilerOptions": { "module": "NodeNext", "target": "ES2022", "checkJs": true, "moduleResolution": "NodeNext" }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] }
- Restart the TS Server (Just in Case): VSCode is usually quick to pick up the new file, but to be sure, you can force it to re-evaluate. Press Ctrl+Shift+P (or Cmd+Shift+P on Mac), type "Restart TS Server", and press Enter. That's it! Your entire project is now being type-checked.
Breaking Down the Configuration
"compilerOptions"
: This is where you configure the behavior of the TypeScript/JavaScript language server."checkJs": true
: This is the golden key. It tells the server to analyze and report errors in all.js
files in your project, not just.ts
files."target": "ES2022"
: This specifies which version of JavaScript your code is written for. It helps the checker know which built-in APIs are available (e.g.,Array.prototype.at()
). Use a version that matches your runtime environment."module": "NodeNext"
: This tells the checker you're using modern ES Modules (import
/export
). Use"CommonJS"
if you're usingrequire()
."include"
: An array of glob patterns specifying which files are part of your project."src/**/*"
is common, meaning "include every file inside thesrc
directory"."exclude"
: An array of files and folders to ignore. You should always excludenode_modules
and any build output directories (likedist
orbuild
).
Wait, Should I Use jsconfig.json
or tsconfig.json
?
You might have also heard of tsconfig.json
. What's the difference? It's simpler than you think. A jsconfig.json
is just a tsconfig.json
with the "allowJs"
property implicitly set to true
.
Here’s a simple table to help you decide:
File | Primary Use Case | When to Use It |
---|---|---|
jsconfig.json |
JavaScript-first projects | Your project is entirely or mostly JavaScript, and you just want to add type-checking via JSDoc. |
tsconfig.json |
TypeScript projects | Your project is written in TypeScript (.ts files) or is a mix of JS and TS and you need to configure the TypeScript compiler. |
The bottom line: If your project is pure JavaScript and you want JSDoc superpowers, use jsconfig.json
. It's purpose-built for you.
Level Up: Advanced Configuration for Peak Performance
Once you're comfortable, you can enhance your jsconfig.json
with more powerful options from the TypeScript compiler:
"strict": true
: This is highly recommended. It enables a suite of strict type-checking rules, includingnoImplicitAny
, which forces you to be explicit about types instead of letting them default toany
. It will make your code significantly more robust."baseUrl": "."
and"paths": { "@/*": ["src/*"] }
: These two options let you set up non-relative module imports. Instead of writingimport MyComponent from '../../../../components/MyComponent'
, you can simply writeimport MyComponent from '@/components/MyComponent'
. A huge quality-of-life improvement!
Troubleshooting: When Things Go Wrong
If you've set up your jsconfig.json
and things still aren't working, here are a few things to check:
- Restart the TS Server: This is the #1 solution. Ctrl+Shift+P -> "TypeScript: Restart TS Server". This forces VSCode to re-read your configuration.
- Check Your
include
/exclude
Paths: Ensure your paths correctly point to your source code and that you're not accidentally excluding it. The paths are relative to the location of thejsconfig.json
file. - Look for Errors in the `Problems` Panel: VSCode will often report issues with your
jsconfig.json
file itself in the "Problems" tab (Ctrl+Shift+M). Look for typos or invalid options.
Conclusion: A New Era of JavaScript Development
By adding a single jsconfig.json
file, you fundamentally change how VSCode sees your project. You elevate it from a loose collection of files to a cohesive, type-aware system. The days of per-file // @ts-check
comments are over.
You now have the power to catch bugs before you run your code, refactor with confidence, and enjoy the rich, intelligent autocompletion that was once the exclusive domain of TypeScript projects. Go ahead, create that file, and unlock a more productive and reliable JavaScript development experience for 2025 and beyond.