Hoi hoi! 👋

I'm @nyaomaru, a frontend engineer who is actually allergic to crabs! 🙀🦀

Today, I have another exciting announcement!

I've just released a new open-source tool called type-tune! 🦀🎉

GitHub logo necoz-oss / type-tune

A Rust-powered CLI to find shared TypeScript types and move them safely. 🦀

type-tune

Animated type-tune logo

Test Docs MIT License

Give shared TypeScript types a better home. 😸

Scan. Review. Move. Validate.

type-tune is a Rust-powered CLI that finds shared TypeScript type aliases and interface declarations and helps move them without manually chasing imports.

It creates a reviewable plan, updates supported type imports and re-exports, and validates the rewrite with TypeScript. You decide what moves and where.

Guides for installation, the first scan, and the review workflow live in the official documentation. Releases are listed on GitHub Releases, and the package is type-tune on npm.

Why type-tune?

Types often start next to a component or utility, then end up shared across a project. Moving them later means tracking imports, local dependencies, and barrels by hand.

  • Discover shared types with deterministic candidate IDs.
  • Review plan.md and choose the destination before making changes.
  • Rewrite supported type-only imports, aliases, and simple barrels while keeping compatibility re-exports at the original…

It's a small CLI tool built with Rust 🦀 that helps you find shared TypeScript types and move them to a better place.

Scan. Review. Move. Validate.

Sounds simple, right?

Well, that's exactly the idea! 😸

🐈 What Is type-tune?

If you've worked on a large TypeScript project, you've probably used tools like Knip.

Knip is awesome! 🎉

It helps us find unused files, exports, and dependencies, making it easier to clean up our codebases.

But there's another problem I've been thinking about.

What about types that are still being used, but aren't organized very well?

TypeScript types are incredibly reusable.

A type declared in one component might eventually be needed by another component, an API module, or even an entire feature.

But in practice, we don't always pay much attention to maintaining our type declarations.

For example, imagine we have this

// src/features/order/OrderPage.tsx export type OrderSummary = { id: string; total: number; }; 

At first, OrderSummary might only be used by OrderPage.

But as the feature grows, other files start importing it.

And sometimes, developers end up declaring similar types again because they don't realize something reusable already exists.

Eventually, we might have:

  • Types scattered across components and utilities.
  • Similar type declarations repeated within the same feature.
  • Shared types living in files that don't really belong to them.
  • Imports that make refactoring unnecessarily complicated.

Everything still works!

But is it easy to maintain?

Hmm, not really. 😹

That's where type-tune comes in!

type-tune finds exported types and interfaces that are already shared across multiple files and helps relocate them to more appropriate locations.

It can also update supported imports and preserve compatibility re-exports, so we don't have to manually chase references around the project.

type-tune workflow

Unlike Knip, which focuses on unused code, type-tune focuses on organizing types that are actually being used.

They're complementary tools!

One helps us remove what we don't need. The other helps us organize what we still need. 😸

💡 Why Did I Build It?

This idea actually came from my own experience.

I was working on refactoring a production codebase with more than 300,000 lines of code.

And one thing kept bothering me.

We weren't making very good use of our existing types.

Even within the same feature, types that could have been shared were sometimes declared separately.

Some types had gradually become shared dependencies, but their locations still reflected where they were originally created.

As the codebase grew, maintaining those relationships became increasingly difficult.

And there was something else I noticed.

🤖 Types Are Even More Valuable in the AI Era

I've been working with AI-assisted development quite a lot recently.

And through that experience, I've come to appreciate TypeScript's type system even more.

Types aren't just there to catch mistakes.

They can also act as useful guardrails for AI coding agents. 🛤️

Well-defined types help communicate the structure of our applications, the relationships between data, and the contracts our code is expected to follow.

In my experience, making those contracts clear is an important part of building an effective AI development workflow.

But there's a catch!

If our types are duplicated, scattered, or poorly maintained, we're not making full use of that information.

So I started wondering

Why don't we have a tool that helps us maintain the structure of our types automatically?

I looked around, but couldn't find a tool that quite solved the problem I had in mind.

So

I decided to build one myself! 🦀🎉

YAY!!!

🚀 How to Use type-tune

Getting started is pretty simple!

📦 Installation

You can install type-tune from npm

npm install -D type-tune 

Or with pnpm (My favorite 😸)

pnpm add -D type-tune 

You can also try it without installing it into your project

npx type-tune scan --project tsconfig.json 

The npm package requires Node.js v22 or later and runs a platform-specific native Rust binary.

And since type-tune is written in Rust, you can also build and install it directly from GitHub using Cargo! 📦

cargo install --git https://github.com/necoz-oss/type-tune --tag v1.0.0 type-tune 

The Rust source requires Rust 1.99 or later.

🔍 Step 1. Find Shared Types

First, scan your TypeScript project

npx type-tune scan --project tsconfig.json 

type-tune analyzes your project and finds candidates for relocation.

By default, it looks for exported types and interfaces referenced by at least two other files.

And don't worry!

Scanning doesn't modify your code. 😸

📋 Step 2. Create a Refactoring Plan

Next, generate a plan

npx type-tune plan \ --project tsconfig.json \ --out .type-tune/plan.json \ --markdown .type-tune/plan.md 

This creates a JSON plan and a Markdown file you can review.

You can inspect which types were found, where they're currently declared, and where they could be moved.

🐈 Step 3. Review the Changes

Here's an important part!

type-tune doesn't decide to move everything automatically.

Every candidate starts as ignore.

You can review the plan and choose which declarations should actually move.

npx type-tune review \ --markdown .type-tune/plan.md 

You can also edit the Markdown plan manually.

I wanted the tool to automate the tedious work while keeping architectural decisions in the developer's hands.

Automation is useful. But control matters too! 😸

🦀 Step 4. Apply the Changes

Once you've reviewed your plan, you can preview the refactoring

npx type-tune apply \ --plan .type-tune/plan.json \ --markdown .type-tune/plan.md \ --dry-run 

type-tune performs the supported rewrites, validates them with TypeScript, and restores the changed files after a normal dry-run.

When you're happy with the plan, run

npx type-tune apply \ --plan .type-tune/plan.json \ --markdown .type-tune/plan.md 

That's it! 🎉

For supported transformations, type-tune handles moving declarations, updating type imports, and validating the result with the TypeScript compiler.

Of course, you should still review the Git diff and run your project's own checks.

✨ Want to Move Just One Type?

There's also a direct extraction command!

npx type-tune extract OrderSummary \ --from src/features/order/OrderPage.tsx \ --to src/features/order/types/order.ts \ --project tsconfig.json \ --dry-run 

Pretty handy, right? 😸

🐈 Let's Build type-tune Together!

I released type-tune under Necoz because I want to build it together with other developers! 😸💚

Necoz · GitHub

A friendly open-source community building small, simple, and useful tools together. 😸 - Necoz

favicon github.com

And this time, with Rust! 🦀

I believe open source becomes even more exciting when we share ideas, learn from each other, and build things together.

So, if you have any ideas, suggestions, or want to contribute, I'd love to hear from you!

Let's grow type-tune together! 🐈

🌱 Just the Beginning!

This is the first public release, v1!

type-tune currently focuses on exported TypeScript type aliases and interface declarations in .ts and .tsx files.

It doesn't automatically merge duplicate type definitions or handle every possible TypeScript refactoring yet.

But I think it's a useful first step toward making type maintenance easier.

And there's still plenty of room to improve!

We'd love to hear about the problems you've encountered while maintaining types in large TypeScript projects.

Maybe you've run into the same challenges!

Or maybe you've found a completely different approach.

Either way, I'd love to learn from your experience! 💚

💚 Check It Out!

type-tune is open source and available on GitHub!

GitHub logo necoz-oss / type-tune

A Rust-powered CLI to find shared TypeScript types and move them safely. 🦀

type-tune

Animated type-tune logo

Test Docs MIT License

Give shared TypeScript types a better home. 😸

Scan. Review. Move. Validate.

type-tune is a Rust-powered CLI that finds shared TypeScript type aliases and interface declarations and helps move them without manually chasing imports.

It creates a reviewable plan, updates supported type imports and re-exports, and validates the rewrite with TypeScript. You decide what moves and where.

Guides for installation, the first scan, and the review workflow live in the official documentation. Releases are listed on GitHub Releases, and the package is type-tune on npm.

Why type-tune?

Types often start next to a component or utility, then end up shared across a project. Moving them later means tracking imports, local dependencies, and barrels by hand.

  • Discover shared types with deterministic candidate IDs.
  • Review plan.md and choose the destination before making changes.
  • Rewrite supported type-only imports, aliases, and simple barrels while keeping compatibility re-exports at the original…




If you find it interesting, please consider giving it a ⭐ on GitHub! 😸

And if you have any ideas, suggestions, or bugs to report, feel free to open an issue or contribute!

Every bit of feedback helps make these little projects better.

🦀 Coming Up Next

Oh, and one more thing!

You might be wondering

Why did I choose Rust instead of TypeScript to build a TypeScript refactoring tool? Is nyaomaru a TypeScript lover, isn't it? 🤔

That's actually an interesting story!

I'll talk about the reasons behind that decision, what I learned while building it, and my experience using Rust in my next article!

Stay tuned! 🦀

Thanks for reading, and happy coding! 😸🙌

💚 Join Our Necoz Community!

Oh, and one more thing! 😸

We also have a Necoz community on DEV! 🎉

Everyone is welcome, whether you're a developer, a writer, or just curious!

Wanna join? Leave a comment below and I'll send you an invitation! 💌

No pressure, no obligations. Just come hang out with us! 🐈

Small. Simple. Useful. Built Together! 💚