Hi everyone! I'm trying to set up a good dev environment for our large TypeScript monorepo (lots of packages, using Turborepo). Every language server I try seems to either crash, use insane memory, or just stop providing intellisense.
I'm on macOS, using VS Code. I've tried:
- The built-in TS/JS language features (just gets slow and unresponsive)
- `typescript-language-server` (seemed promising but crashed a lot)
- `deno lsp` (had some path resolution issues)
My `.vscode/settings.json` looks like this currently, but I'm not sure it's optimal:
```json
{
"typescript.tsserver.maxTsServerMemory": 4096,
"typescript.tsserver.experimental.enableProjectDiagnostics": true
}
```
Has anyone found a setup that actually works? I'd love a beginner-friendly explanation of what to try next. Thanks in advance for any tips! 🙏
The built-in TS server is actually what you want, but you need to configure it to handle the monorepo correctly. Your memory setting is okay, but that diagnostic flag might be making it work harder than needed.
First, try disabling `enableProjectDiagnostics`. That runs checks across all projects constantly and can bring things to a crawl in a monorepo. Also, set `"typescript.tsserver.useSeparateSyntaxServer": false`. The separate syntax server can cause issues with large workspaces.
More importantly, your problem is likely path and project detection. Make sure you have a `tsconfig.json` in the root of your workspace that references your packages, and set `"typescript.disableAutomaticTypeAcquisition": true`. You want VS Code to use your local `node_modules/typescript` and your explicit tsconfig, not go hunting.
If it's still slow, look at your `tsconfig.json` includes/excludes. You might be accidentally pulling in `dist` folders or `node_modules`. That'll blow up the project graph.
Build once, deploy everywhere
Yes, the built-in server can be tamed! You're spot-on about disabling `enableProjectDiagnostics` - that's often the first culprit for memory bloat. I'd add one more setting to your list: `"typescript.tsserver.experimental.enableProjectDiagnostics": false`. Wait, that's the same one you mentioned disabling. Let me rephrase - make absolutely sure it's off.
I had a similar struggle with our marketing automation platform's monorepo. The turning point for me was the `"typescript.tsserver.watchOptions"` setting in the VS Code config. Adding `"watchOptions": { "watchFile": "priorityPollingInterval", "watchDirectory": "dynamicPriorityPolling" }` significantly reduced the CPU load from file watching across hundreds of packages. It's a game-changer that's rarely mentioned.
One caveat to your excellent advice about a root `tsconfig.json`: in a Turborepo setup, you might not want a *single* root config that references everything. Sometimes, letting VS Code manage each package's own `tsconfig.json` independently, but setting `"typescript.preferences.autoImportFileExcludePatterns"` to avoid cross-package chaos, works better. It depends on how coupled your packages are. Have you experimented with both approaches?
test everything twice