iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🏗️

The Fastest Way to Build the Best TypeScript Development Environment: Autumn 2025

に公開

In this article, we will set up a TypeScript development environment as quickly as possible. This won't just be an environment that barely works; we'll also include a full set of the minimum necessary tools. (Information as of Autumn 2025)

About the Development Environment Created in This Article

The Goal of This Article

  • Execute TypeScript files with the bun run command
  • Launch the REPL with the bun repl command to execute TypeScript
  • Perform (strict) type checking with the bun tsc --noEmit command
  • Enable code completion and type checking with the TypeScript Language Server
  • Format and lint code with the bun biome command
  • Run linting during development via the Biome extension
  • Automatically perform formatting and auto-fixes on save via the Biome extension
  • Execute test code with the bun test command
  • Run tests directly from source code via the Bun extension
  • Run tests in debug mode via the Bun extension
  • People who want an environment where they can comfortably code and run TypeScript right away!
  • People who have no idea what an OS, terminal, or directory is.

    • -> Please research carefully and proceed with understanding. You are responsible for any issues that may occur.
  • People who cannot read English at all.

    • -> The official websites for the tools we install are in English. Please use translation tools or refer to Japanese articles for guidance.
  • People who don't have a PC and want to do it on a smartphone or tablet.

    • -> The software used is not compatible with mobile OSs, so it's not possible. If you just want to try it out briefly in a browser, https://www.typescriptlang.org/play/ is useful.
  • People who prefer Node.js, Deno, or ESLint.

    • -> The tools and procedures are slightly different. While parts of this article might be helpful, it might be better to look for articles specifically for those tools.
  • People who want to try a specific framework like Next.js or Hono.

    • -> I recommend the official quick starts for each framework. This article may still be partially helpful.
  • People who want to go all the way to building and deploying.

    • -> That is a bit beyond the scope of this article. It might be helpful up to a certain point.

Why Bun? Why Biome?

Bun

https://bun.com

Bun is an all-in-one tool: JavaScript runtime, package manager, TypeScript runtime, bundler, and test runner.

  • The initial setup cost is lower compared to configurations that collect individual packages like Node.js + pnpm + tsx + vite + vitest.
  • Since Bun's package management and built-in APIs are Node.js compatible, it has more community resources available compared to Deno and is easier to use.
  • While some express concerns about project stability, it is more than sufficient for quickly trying things out locally.

Biome

https://biomejs.dev/ja/

Biome is a fast, all-in-one formatter and linter.

  • Bun does not include formatter or linter functions. Since it's difficult to work without them, we will include Biome.
  • It can replace the traditional combination of ESLint + Prettier with just this one tool.
  • While it offers less customizability than ESLint, the setup is, above all, very simple.

1. Install VS Code

If VS Code is not installed, please install it from the official website.

https://code.visualstudio.com/

Basically, you can install it by following the steps from the download button that appears first.

If a VS Code fork like Cursor is already installed, you can use that instead.

VS Code comes pre-installed with a Language Server that assists in TypeScript development.
Additionally, extensions for various TypeScript-related tools are primarily provided for VS Code.

The default language setting is English. Japanese localization is optional.

2. Install Bun

Install Bun by following the official website.

https://bun.com/docs/installation

The installation method varies by OS, and some methods may require prerequisite tools.

If you are not familiar with this, please research the surrounding information carefully while installing.

3. Create a Project

Prepare an empty directory (folder) with a name of your choice. As a convention, it is recommended to use only lowercase alphanumeric characters and hyphens (-) for the project directory name.

TERMINAL
mkdir setup-typescript-2025-autumn

Open the prepared directory in VS Code.

TERMINAL
code setup-typescript-2025-autumn

Open the terminal within VS Code.
You can open it using Ctrl + Shift + ` or from the Terminal option in the toolbar at the top of the window.

Once the terminal is open, run bun init to set up a new Bun project. Select Blank for the project type.

TERMINAL
bun init

If this command fails with a command not found error, your PATH might not be set up correctly. Try configuring your PATH according to the official documentation.

4. TypeScript Configuration

The type-checking settings in the tsconfig.json generated by bun init are a bit loose, so let's make them stricter. Execute the following command to install the shared presets from tsconfig/bases as development dependencies.

TERMINAL
bun add -D @tsconfig/bun @tsconfig/strictest

Replace the contents of tsconfig.json with the following:

tsconfig.json
{
    "extends": ["@tsconfig/bun", "@tsconfig/strictest"],
    "exclude": ["node_modules", "out", "dist"]
}

The priority of settings is bun < strictest (the latter takes precedence).

5. Introducing Biome

Run the following command to install Biome as a development dependency.

TERMINAL
bun add -D @biomejs/biome

Create the recommended configuration file using the bun biome init command.

TERMINAL
bun biome init

Modify the created biome.json configuration file. We will specify files to be ignored for formatting and adjust some of the more opinionated settings to your preference.

biome.json
  {
    "files": {
-       "ignoreUnknown": false
+       "ignoreUnknown": false,
+       "includes": ["**", "!**/node_modules", "!**/out", "!**/dist"]
    },
      "formatter": {
          "enabled": true,
-         "indentStyle": "tab"
+         "indentStyle": "space",
+         "indentWidth": 4,
+         "lineWidth": 120
       },
       "javascript": {
           "formatter": {
-              "quoteStyle": "double"
+              "quoteStyle": "single"
           }
       },
  }

6. Introducing VS Code Extensions

Install the Biome extension to detect linter rule violations during development. You can install it from the VS Code Marketplace below:

https://marketplace.visualstudio.com/items?itemName=biomejs.biome

Once installed, configure it to automatically format using Biome when saving files. Let's create .vscode/settings.json under the project root.

.vscode/settings.json
{
  "editor.formatOnSave": true,
  "[json]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[javascript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[typescript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "editor.codeActionsOnSave": {
    "source.fixAll.biome": "explicit",
    "source.organizeImports.biome": "explicit"
  }
}

Now, files like .ts will be automatically formatted when you save them with Ctrl + S.
Note that if you have VS Code's auto-save setting turned on, it will not format on auto-save.

Next, let's also introduce the Bun extension so that you can easily execute test code. You can install it from the VS Code Marketplace below:

https://marketplace.visualstudio.com/items?itemName=oven.bun-vscode

Once installed, configure it so that you can debug your test code. Following the instructions on the Bun extension page, create .vscode/launch.json under the project root.

.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "bun",
      "request": "launch",
      "name": "Debug Bun",

      // The path to a JavaScript or TypeScript file to run.
      "program": "${file}",

      // The arguments to pass to the program, if any.
      "args": [],

      // The working directory of the program.
      "cwd": "${workspaceFolder}",

      // The environment variables to pass to the program.
      "env": {},

      // If the environment variables should not be inherited from the parent process.
      "strictEnv": false,

      // If the program should be run in watch mode.
      // This is equivalent to passing `--watch` to the `bun` executable.
      // You can also set this to "hot" to enable hot reloading using `--hot`.
      "watchMode": false,

      // If the debugger should stop on the first line of the program.
      "stopOnEntry": false,

      // If the debugger should be disabled. (for example, breakpoints will not be hit)
      "noDebug": false,

      // The path to the `bun` executable, defaults to your `PATH` environment variable.
      "runtime": "bun",

      // The arguments to pass to the `bun` executable, if any.
      // Unlike `args`, these are passed to the executable itself, not the program.
      "runtimeArgs": [],
    },
    {
      "type": "bun",
      "request": "attach",
      "name": "Attach to Bun",

      // The URL of the WebSocket inspector to attach to.
      // This value can be retrieved by using `bun --inspect`.
      "url": "ws://localhost:6499/",
      // Optional path mapping for remote debugging
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "/app",
    },
  ],
}

7. Verification

This completes the setup steps. Let's check if our goals have been achieved.

Execute TypeScript files with the bun run command

Create index.ts in the project root. It should have already been created by bun init.

index.ts
console.log('Hello via Bun!');

Try executing this TypeScript file with bun run index.ts.

TERMINAL
bun run index.ts

If "Hello via Bun!" is displayed in the standard output, the goal is achieved!

TERMINAL
Hello via Bun!

Launch the REPL and execute TypeScript with the bun repl command

Launch the REPL with the bun repl command.
The REPL is a feature that allows you to write and execute source code directly in the terminal.

TERMINAL
bun repl

Once the REPL has started, try entering and executing TypeScript code at the prompt. Enter the source code and press Enter to execute.

TERMINAL
const msg: string = 'REPL OK';
// > undefined
msg.toLowerCase();
// > repl ok

If you can execute TypeScript code with type annotations in the REPL, the goal is achieved!

To exit the REPL, enter .exit at the prompt or press Ctrl + D on your keyboard.

Perform (strict) type checking with the bun tsc --noEmit command

Edit index.ts and add the following line.

index.ts
// Cause an unused variable error
const unused = 123;

In this state, try running the bun tsc command.

TERMINAL
bun tsc --noEmit

If the following error is displayed due to the @tsconfig/strictest setting, the goal is achieved!

TERMINAL
index.ts:1:7 - error TS6133: 'unused' is declared but its value is never read.

Enable code completion and type checking with the TypeScript Language Server

Open index.ts and experience the code completion and type checking features of the TypeScript Language Server.

index.ts
console.log('As soon as you type console.l, log appears as a suggestion.');
const value: number = 'Since a string is being assigned to a number, a type check error is displayed.';

If you can confirm that code completion and type checking are working, the goal is achieved!

Format and lint with the bun biome command

Open index.ts and intentionally create code with broken formatting and rule violations. Since it will be automatically formatted if you save with Ctrl + S, save it using Ctrl + K, Ctrl + Shift + S instead.

index.ts
const  fixMe:String= 'fix me!'
// Improper spacing, missing semicolon, inappropriate type, unused variable

Run bun biome check to execute the check for formatting differences and lint rule violations.

TERMINAL
bun biome check

If formatting differences and lint rule violations are pointed out, it's a success.
(This command does not perform automatic formatting or auto-fixes.)

TERMINAL
  ! This variable fixMe is unused.

  > 1 │ const  fixMe:String= 'fix me!'
      │        ^^^

  ! Don't use 'String' as a type.

  > 1 │ const  fixMe:String= 'fix me!'
      │            ^^^^^^

  × Formatter would have printed the following content:

    1   │ - const··fixMe:String=·'fix·me!'
      1 │ + const·fixMe:·String·=·'fix·me!';
      2 │ +

Try automatic formatting by running bun biome format --write.

TERMINAL
bun biome format --write

If you can confirm that the file is formatted, it's a success.
(This command does not automatically fix rule violations.)

Try automatic fixing of rule violations by running bun biome lint --write.

TERMINAL
bun biome lint --write

If you can confirm that String is corrected to string, it's a success.
(This command does not automatically fix the unused variable issue.)

The goal of executing formatting and linting via commands is now achieved!

Run linting during development via the Biome extension

Open index.ts and create code with the same broken formatting and rule violations as before.

index.ts
const  fixMe:String= 'fix me!'
// Improper spacing, missing semicolon, inappropriate type, unused variable

In this state, hover over fixMe or String.
If you can confirm that the same rule violation errors are displayed without any commands, the goal is achieved!

Automatically perform formatting and auto-fixes on save via the Biome extension

Open index.ts and create the same code with broken formatting and rule violations as before.

index.ts
const  fixMe:String= 'fix me!'
// Improper spacing, missing semicolon, inappropriate type, unused variable

In this state, try saving with Ctrl + S.
If it is automatically corrected as follows, the goal is achieved!

index.ts
const fixMe: string = 'fix me!';

Execute test code with the bun test command

Add one test file to check if the test runner works.

Create index.test.ts in the project root and add the following test code.

index.test.ts
import { describe, expect, it } from 'bun:test';

describe('math', () => {
  it('adds numbers', () => {
    const result = 1 + 2;
    expect(result).toBe(3);
  });
});

Execute the tests with the bun test command.

TERMINAL
bun test

If the tests run and you see results like the following, the goal is achieved!

TERMINAL
index.test.ts:
✓ math > adds numbers

 1 pass
 0 fail
 1 expect() calls
Ran 1 test across 1 file. [37.00ms]

Run tests directly from source code via the Bun extension

Next, let's check if we can run tests directly from the source code.

When you open index.test.ts, do you see a play button to the left of the line starting with describe('math'? Let's click it.

If the pane at the bottom of the screen switches to TEST RESULTS and displays the same test results as before, the goal is achieved!

TEST RESULTS
index.test.ts:
✓ math > adds numbers

 1 pass
 0 fail
 1 expect() calls
Ran 1 test across 1 file. [37.00ms]

Run tests in debug mode via the Bun extension

Next, we will check if we can debug tests using breakpoints in VS Code.

Open index.test.ts and click to the left of the line number for expect(result).toBe(3); to set a breakpoint. It's a success if a red circle appears.

In this state, right-click the button to the left of the line starting with describe('math' (it was a play button earlier, but should now be a success mark since the test passed once) and select "Debug Test".

The test will execute, but it will pause at the breakpoint.
If the left pane switches to the debug pane and the content of the variable result is displayed in VARIABLES > Locals, the goal is achieved!

Run and Debug > VARIABLES > Locals
  result = 3

To resume the paused test, press the resume button on the debug controller displayed at the top of the screen.

And that's it! You have now completed the ultimate TypeScript + Bun + Biome development environment!

Conclusion

That concludes the introduction to the minimal configuration I usually use. This is likely the fastest and most convenient method.

I feel that setup has become significantly easier thanks to Bun and Biome. For quickly writing code, Bun is currently the easiest choice.

Next, you can define your favorite commands in package.json > scripts, set it up as a Git repository with git init, or add utility libraries like type-fest or remeda. Since the linter and testing tools are all set up, you can even start "Vibe Coding" with a Coding Agent!

Wishing you a great development experience in a great development environment. Happy Hacking! 🎉

Discussion