Import Polisher
Automatically beautify and reorganize import statements while guaranteeing zero changes to runtime behavior.

Features
- Smart Import Grouping — Organizes imports by category (builtin, external, sibling, parent, internal, side-effect)
- Named Import Sorting — Sorts members inside
{ } braces by length (shorter first)
- Multi-Language Support — TypeScript, JavaScript, Python, Go, Rust, Java, Kotlin, Swift, Dart, C#, PHP, C/C++, Ruby, Scala, Elixir
- AST-Based Parsing — Uses syntax trees for accurate import detection (falls back to regex if AST fails)
- Comment Preservation — Comments attached to imports remain attached after reordering
- Zero Runtime Changes — Never modifies executable code
- Deterministic Output — Running multiple times produces the same result
- Format on Save — Automatically beautifies imports when you save (Ctrl+S)
- Format on Paste — Optionally beautifies imports after pasting (Ctrl+V)
Default Behavior
With default settings (sortOrder: "length", sortNamedImports: true, groupByCategory: false), Import Polisher:
- Sorts imports by length (shorter module names first)
- Sorts named imports inside
{ } by length
- Puts all imports together (no group separation)
Example: Default Changes
Before:
import { z, a, m } from 'zod';
import fs from 'fs';
import { sortImports } from './utils';
import path from 'path';
import express from 'express';
import { helper } from '@/helpers';
import './polyfills';
After:
import fs from 'fs';
import './polyfills';
import path from 'path';
import { a, m, z } from 'zod';
import express from 'express';
import { helper } from '@/helpers';
import { sortImports } from './utils';
What changed:
fs and path moved to the top (shorter names)
{ z, a, m } became { a, m, z } (sorted by length)
- All imports sorted together by module name length
Example: Python
Before:
from mypackage.utils import helper, formatter
import json
from .models import User
import sys
from typing import Optional, List, Dict
After:
import json
import sys
from mypackage.utils import formatter, helper
from typing import Dict, List, Optional
from .models import User
What changed:
- Builtins (
json, sys) moved to the top
- Named imports sorted by length (
Dict, List, Optional)
Example: With Group Spacing
Enable groupSpacing: true to add blank lines between import groups:
Before:
import { z, a, m } from 'zod';
import fs from 'fs';
import { sortImports } from './utils';
import path from 'path';
import express from 'express';
import { helper } from '@/helpers';
After:
import fs from 'fs';
import path from 'path';
import express from 'express';
import { a, m, z } from 'zod';
import { helper } from '@/helpers';
import { sortImports } from './utils';
Example: Alphabetical Sort
Set sortOrder: "alphabetical" for A-Z ordering:
Before:
import { zebra, apple, mango } from 'fruits';
import express from 'express';
import path from 'path';
After:
import path from 'path';
import express from 'express';
import { apple, mango, zebra } from 'fruits';
Example: TypeScript with Type Imports
Before:
import { useState, useEffect, type ReactNode, type FC } from 'react';
import express from 'express';
import { z } from 'zod';
import fs from 'fs';
After:
import fs from 'fs';
import express from 'express';
import { z } from 'zod';
import { FC, ReactNode, useEffect, useState, type FC, type ReactNode } from 'react';
How Import Polisher Rearranges Imports
Import Polisher uses a two-phase sorting algorithm:
Phase 1: Group Classification
Each import is classified into one of 6 groups based on the module specifier:
| Group |
Description |
Examples |
builtin |
Node.js built-in modules |
fs, path, node:fs, node:path |
external |
Third-party packages |
react, lodash, express, zod |
internal |
Your app's internal paths |
@/utils, src/lib, ~/helpers |
parent |
Parent directory imports |
../utils, ../../config |
sibling |
Same-directory imports |
./utils, ./helpers |
side-effect |
Side-effect imports |
import "./styles.css" |
Phase 2: Sorting Within Groups
After grouping, imports are sorted within each group based on the sortOrder setting:
| Sort Order |
Algorithm |
Example |
length |
Shorter strings first (default) |
fs, path, express |
alphabetical |
Standard A-Z sorting (case-sensitive) |
Apple, banana, Cherry |
case-insensitive |
Ignores case when comparing |
Apple, banana, Cherry |
Phase 3: Named Specifier Sorting
If sortNamedImports is true, members inside { } braces are also sorted:
Before:
import { zebra, apple, mango } from 'fruits';
After:
import { apple, mango, zebra } from 'fruits';
Configuration Options
| Setting |
Type |
Default |
Description |
importPolisher.formatOnSave |
boolean |
true |
Auto-format when saving a file |
importPolisher.formatOnPaste |
boolean |
false |
Auto-format after pasting code |
importPolisher.sortOrder |
string |
"length" |
Sort algorithm for imports |
importPolisher.groupByCategory |
boolean |
false |
Group imports by category |
importPolisher.groupOrder |
string[] |
See below |
Order of import groups |
importPolisher.groupSpacing |
boolean |
false |
Add blank lines between groups |
importPolisher.sortNamedImports |
boolean |
true |
Sort { a, b } → { a, b } |
importPolisher.useAST |
boolean |
true |
Use AST parsing (more accurate) |
importPolisher.enabledLanguages |
string[] |
[] |
Limit to specific languages |
importPolisher.debug |
boolean |
false |
Enable debug logging |
Settings JSON
Add to your settings.json:
{
"importPolisher.sortOrder": "length",
"importPolisher.groupByCategory": false,
"importPolisher.groupOrder": [
"builtin",
"external",
"sibling",
"parent",
"internal",
"side-effect"
],
"importPolisher.groupSpacing": false,
"importPolisher.sortNamedImports": true,
"importPolisher.useAST": true,
"importPolisher.debug": false,
"importPolisher.enabledLanguages": []
}
Usage
Keyboard Shortcuts
| Action |
Windows/Linux |
Mac |
| Beautify Imports |
Ctrl+Alt+I |
Cmd+Alt+I |
| Beautify Workspace |
Ctrl+Alt+Shift+I |
Cmd+Alt+Shift+I |
| Save & Beautify |
Ctrl+S |
Cmd+S |
Commands
Open the Command Palette (Ctrl+Shift+P) and type:
| Command |
Description |
Import Polisher: Beautify Imports |
Beautify imports in the current editor |
Import Polisher: Beautify Current File |
Beautify the active file |
Import Polisher: Beautify Workspace |
Beautify all supported files in the workspace |
Import Polisher: Toggle Format on Save |
Enable/disable auto-format on save |
Import Polisher: Toggle Format on Paste |
Enable/disable auto-format on paste |
Supported Languages
| Language |
Parser |
Type Imports |
| TypeScript |
AST (TypeScript Compiler API) |
Yes |
| JavaScript |
AST (TypeScript Compiler API) |
No |
| TSX |
AST (TypeScript Compiler API) |
Yes |
| JSX |
AST (TypeScript Compiler API) |
No |
| Python |
Regex-based |
No |
| Go |
Regex-based |
No |
| Rust |
Regex-based |
No |
| Java |
Regex-based |
No |
| Kotlin |
Regex-based |
No |
| Swift |
Regex-based |
No |
| Dart |
Regex-based |
No |
| C# |
Regex-based |
No |
| PHP |
Regex-based |
No |
| C/C++ |
Regex-based |
No |
| Ruby |
Regex-based |
No |
| Scala |
Regex-based |
No |
| Elixir |
Regex-based |
No |
Installation
From .vsix
code --install-extension import-polisher-0.0.1.vsix
From Source
git clone https://github.com/your-username/import-polisher.git
cd import-polisher
npm install
npm run build-extension
code --install-extension import-polisher-0.0.1.vsix
Or press F5 in VS Code to launch the Extension Development Host.
Architecture
src/
├── extension.ts # Extension entry point
├── commands/ # VS Code command handlers
│ └── beautify.ts # Beautify imports command
├── models/ # Data models and interfaces
│ └── import.ts # Import types, groups, config
├── parsers/ # Language-specific parsers
│ ├── typescript-parser.ts # TS/JS/TSX/JSX (AST)
│ ├── python-parser.ts # Python (regex)
│ └── generic-parser.ts # Other languages (regex)
├── sorters/ # Import and specifier sorting
│ └── import-sorter.ts # Sorting algorithms
├── languages/ # Language registry
│ └── registry.ts # Language configuration
├── services/ # Core services
│ └── formatter.ts # Main formatting logic
├── settings/ # Configuration management
│ └── settings.ts # VS Code settings reader
└── utils/ # Utility functions
└── logger.ts # Debug logging
Development
npm install
npm run compile # Compile once
npm run watch # Watch mode (auto-recompile)
npm run lint # Lint source files
npm run build-extension # Package as .vsix
After packaging, install the built extension locally:
code --install-extension import-polisher-0.0.1.vsix
Contributing
We welcome contributions! For detailed instructions on development setup, testing, debugging, and publishing, see docs/CONTRIBUTING.md.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature)
- Commit your changes (
git commit -m 'Add amazing feature')
- Push to the branch (
git push origin feature/amazing-feature)
- Open a Pull Request
License
MIT License - see LICENSE for details.