Skip to content
| Marketplace
Sign in
Visual Studio Code>Linters>TinyPortNew to Visual Studio Code? Get it now.
TinyPort

TinyPort

Vantaso

|
1 install
| (0) | Free
Live import weight in the editor: see what every import costs, sort and clean up, right where you're editing.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

TinyPort for VS Code

Live import weight in the editor, the same analysis as the tinyport CLI and the @tinyport/mcp server, rendered where you're editing, not run on demand.

This extension holds no analysis logic of its own: it supplies VS Code's filesystem and an esbuild bundler to @tinyport/core's ports, and renders the Report core hands back. If a decision about an import's size, order, or findings shows up in this package instead of @tinyport/core, that's a bug.

Install

Install TinyPort from the VS Code Marketplace, or from Quick Open (Cmd/Ctrl+P):

ext install vantaso.tinyport-vscode

Open any JavaScript or TypeScript file and every import grows a size tag. No configuration required.

What it does

  • Inline size at the end of every import line, import { motion } from "framer-motion" gets a 114 kB tag, import { clsx } from "clsx" gets 600 B. Coloured green under a per-package budget, amber approaching it, vermilion over, muted when no budget is set. A whole-statement import type and an unresolved relative import show nothing; there's nothing true to print for either.
  • Gutter bars sized relative to the heaviest import in the file, so the worst offender is visible without reading a single number.
  • Hover over any import for its resolved size (bundled, shipped, or type-only), and a lighter alternative when TinyPort's built-in table knows one (e.g. moment → date-fns/dayjs, lodash → per-function imports).
  • Diagnostics in the Problems panel for unused imports (dimmed in the editor too) and a file that's over its budget.
  • Six commands (Command Palette: search "TinyPort") and matching sort/remove code actions, all built on the exact same planners the CLI's fix/report commands use, never a second implementation:
    • TinyPort: Sort Imports, sorts and groups, one undoable edit.
    • TinyPort: Sort and Remove Unused, sorts and drops unused imports, one undoable edit.
    • TinyPort: Show Import Report, a full per-file breakdown in an output channel, plus a one-line total.
    • TinyPort: Scan Project for Heavy Imports, ranks every imported package across the workspace, cancellable.
    • TinyPort: Set Budget for this Workspace, sets a file or package byte budget.
    • TinyPort: Toggle Accurate (Bundled) Sizing, flips tinyport.bundled.
  • Status bar item with the active file's total (190 kB / 100 kB when a file budget is set, vermilion background when over); click it to run the file report.
  • Sort-on-save, off by default, that refuses to turn itself on when it detects a competing import organiser already doing the job, see below.

Sizes work out of the box

Every surface above works the moment you install this extension, no configuration, no esbuild of your own required. The default is a disk-based estimate (shipped): the installed size of the package(s) a specifier resolves to, instant and offline. Turn on tinyport.bundled for the real, measured number, the actual minified + gzipped bytes a bundler would ship for that specific import (e.g. next/link is 47.5 kB installed but 15.2 kB gzipped once actually bundled), TinyPort prefers the analysed project's own esbuild and falls back to a copy of its own when the project has none, so accurate sizing works out of the box too. Real bundling is slower and runs off the hot path: typing never blocks on it, and inline decorations keep using the instant disk estimate even with tinyport.bundled on, only a hover or an explicit report picks up the measured number once it resolves. Every figure that leans on the disk estimate is marked (est), so an estimate is never mistaken for a measurement.

Settings

All under tinyport.*:

Setting Default What it does
tinyport.showInlineSize true Inline size decoration at the end of each import line.
tinyport.showGutterBars true Gutter bar sized relative to the file's heaviest import.
tinyport.greyOutUnused true Dims imports TinyPort detects as unused.
tinyport.bundled false Measure real bundled + gzipped size via esbuild instead of the disk estimate. Slower; off the inline-decoration hot path regardless.
tinyport.sortBy "size" Order within a group: size, length, alpha, or natural.
tinyport.sortDirection (unset) asc or desc. Unset follows sortBy, desc for size, asc otherwise.
tinyport.groups ["builtin", "external", "internal", "parent", "sibling"] Ordered import groups; a blank line separates each group present in a file.
tinyport.budget.file null Per-file size budget in bytes. null disables it.
tinyport.budget.package null Per-package size budget in bytes. null disables it.
tinyport.printWidth null Line width when planning a rewrite. null infers from Prettier/EditorConfig when available, otherwise 100.
tinyport.alternatives {} Extra package -> lighter-alternative entries, merged over TinyPort's built-in table.
tinyport.sortOnSave false Sort imports automatically on save. See below.
tinyport.removeUnusedOnSave false Experimental. Also remove unused imports on save, independent of sortOnSave. Stays experimental and off until the removal path has had an independent re-review.

A keybinding (alt+shift+o, editor focus) runs tinyport.sortImports.

Sort-on-save and the conflict problem

tinyport.sortOnSave is off by default, and turning it on doesn't unconditionally make TinyPort sort every save: before it acts, it checks the workspace for another tool already doing the same job,

  • editor.codeActionsOnSave's source.organizeImports (either shape VS Code accepts, the per-kind object or the flat array),
  • an ESLint rule (import/order, simple-import-sort/imports, perfectionist/sort-imports) enabled in the nearest config,
  • a Prettier import-sort plugin (@ianvs/prettier-plugin-sort-imports, @trivago/prettier-plugin-sort-imports).

If it finds one, it names the tool in a warning notification and does not sort, checked fresh on every single save, not just once when the setting is turned on, so a conflict introduced later (a new ESLint rule, a teammate's Prettier config change) still gets caught on the very next save rather than silently fighting the other tool. Want TinyPort specifically, alongside another organiser? Add "source.organizeImports.tinyport": true to editor.codeActionsOnSave for explicit sequencing, TinyPort's own code-action kind never trips its own conflict check.

Removal is never a save side effect of sortOnSave: tinyport.removeUnusedOnSave is a separate, independent, experimental setting, turning one on does not turn on the other.

Running it from source

To hack on the extension (rather than install the Marketplace build), run it in the Extension Development Host:

  1. From the repo root, build every package once (the extension depends on @tinyport/core and @tinyport/node-support's built output):

    pnpm install
    pnpm -r build
    
  2. Open the repo root in VS Code and press F5 (or Run ▸ Start Debugging), using the Run TinyPort Extension launch configuration (.vscode/launch.json at the repo root). This runs the extension's own build (.vscode/tasks.json's tinyport-extension: build task, pnpm --filter tinyport-vscode build) as a preLaunchTask, then opens a second Extension Development Host window with this extension loaded.

    No launch config handy? Run the build yourself and start the host by hand:

    pnpm --filter tinyport-vscode build
    code --extensionDevelopmentPath="$(pwd)/packages/extension"
    
  3. In the Extension Development Host window, open a .js/.ts/.jsx/.tsx file with a few node_modules imports (this activates the extension, see activationEvents in package.json). Each import line should grow a size tag at its end and a bar in the gutter within ~300 ms; the status bar (bottom right) should show the file's total.

Re-run step 2 (or just the build command) after changing extension source, the dev host doesn't hot-reload; use Developer: Reload Window inside it, or stop and re-launch, to pick up a rebuilt dist/extension.js.

Development

pnpm vitest run packages/extension        # pure builders/adapters, no editor needed
pnpm --filter tinyport-vscode test:integration   # @vscode/test-electron, needs a real download+launch
pnpm typecheck
node ../../scripts/check-versions.mjs     # this package's version must track the workspace
pnpm --filter tinyport-vscode build       # produces dist/extension.js, a single bundled CJS file
pnpm --filter tinyport-vscode package     # produces the .vsix, see scripts/package-vsix.mjs

config.ts, analysis/engine.ts (the only module that calls into @tinyport/core), analysis/debounce.ts, actions/offsets.ts, and every ui/*/actions/*/save/* module except the ones ending Manager.ts/Controller.ts/onSave.ts are pure and unit-tested with vitest, no VS Code runtime needed. A static import "vscode" anywhere in a module's graph makes it unloadable outside the extension host, so the colour thresholds, the (est) suffix, the sort/remove plans, and the sort-on-save conflict detector are all provable in vitest; only the thin wiring that turns those specs into real vscode.* API calls needs an editor, and that thin layer is what test-integration/ (@vscode/test-electron) exists to cover, activation, a command mutating and undoing a real buffer, sortOnSave actually gating a real save, and actions/offsets.ts's offset-to-position conversion checked against VS Code's own document.positionAt across CRLF, lone-\r, and multi-UTF-16-unit text.

Status

Every feature in What it does is built and tested. Not in v1, deliberately:

  • Registry metadata in the hover (version, deprecated, outdated), has a slot, waits on a later tier.
  • "Switch to alternative" as an action, hover names an alternative; rewriting call sites for you needs preview discipline this version doesn't have yet.
  • removeUnusedOnSave graduating out of experimental.
  • A web extension host, desktop only for now.

MIT © 2026 Muhammad Ali

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft