Tack — Code Comments & Sticky NotesPin comments to lines of code and share them with your team through git. Tack keeps notes where the code is, follows them as the code moves, and commits them so the next developer actually sees them. It also gives you a free-floating sticky note board for everything that isn't about one particular line. Two independent features, with no overlap between them:
Why not just write a
|
| Layer | What you get |
|---|---|
| The line | A single comment icon, from VS Code's own comment widget |
| Hover | The full text, its author, plus Edit · Delete |
| Inline box | Click the icon to expand an editable, multi-line box |
| Overview ruler | A mark in the scrollbar so it stays findable in a long file |
Nothing is drawn in the breakpoint gutter and nothing is appended after your code.
Comments follow the code
This is the hard part, and Tack takes it seriously.
While a file is open, every edit is translated exactly: insert ten lines above a comment and it moves down ten lines. No guessing, no drift.
When a file changes behind VS Code's back — a git pull, a branch switch, an
editor you never had open — the comment is re-found by matching the text of the
line it was attached to, searching outward from where it used to be and using the
surrounding lines to choose between duplicates.
If the line is genuinely gone, the comment is marked detached rather than deleted. It moves to a Detached group in the sidebar and you can re-anchor it to a new line. Comments are never silently lost.
Built for a team
Every comment records who wrote it, taken from git config user.name, and shows
that name in the widget, the hover and the sidebar. The storage file is sorted by
file and then by line, so two people commenting on the same file produce a small,
readable merge conflict instead of an unreadable one.
Feature two: the sticky note board
An infinite canvas for the thinking that isn't about one particular line — a plan, a question, a scratch list.
| Action | How |
|---|---|
| New note | + New note, double-click the canvas, or press N |
| Edit | Click into a note and type — saves as you go |
| Move | Drag a note by its paper strip along the top |
| Resize | Drag the bottom-right corner |
| Recolour | Click the colour dot: yellow, pink, blue, green, orange, purple |
| Delete | The × on the strip — an Undo button appears for a few seconds |
| Pan | Drag empty canvas, or scroll |
| Zoom | Ctrl + wheel, or the Fit / 100% buttons |
Commands
Everything is under the Tack prefix in the command palette.
| Command | Description |
|---|---|
Tack: Add Comment at Cursor |
Comment on the current line |
Tack: Edit Comment |
Open the inline box for a comment |
Tack: Reveal Comment |
Jump to a comment's line |
Tack: Re-anchor Comment at Cursor |
Give a detached comment a new line |
Tack: Delete Comment |
Delete, with an undo prompt |
Tack: Open Comments File |
Open .tack/comments.json |
Tack: Open Board |
Open (or reveal) the board |
Tack: New Note |
Drop a fresh note on the board |
Tack: Reveal Note on Board |
Fly to a note on the canvas |
Tack: Change Note Colour |
Pick a paper colour |
Tack: Delete Note |
Delete, with an undo prompt |
Tack: Open Board File |
Open .tack/board.json |
Sharing with your team
Commit .tack/comments.json. That is the whole point — a comment nobody else
can see is just a private note.
.tack/ is deliberately not under .vscode/, which a great many projects
gitignore wholesale. Storing shared data there would have it silently excluded
from commits, with nothing to warn you.
The board sits in the same directory and is shared by default too. If you would
rather keep it to yourself, add one line to .gitignore:
.tack/board.json
Storage format
.tack/comments.json, grouped by file and ordered by line so git diffs stay
small:
{
"version": 1,
"comments": [
{
"id": "7b1f3c2a-9d4e-4a61-8f0b-2c5d6e7a8b90",
"text": "Rewrite the retry backoff before the release.",
"path": "src/net/retry.ts",
"line": 41,
"fingerprint": "const delay = base * 2 ** attempt;",
"context": "1n7kq2",
"author": "Ada Lovelace",
"createdAt": "2026-09-03T18:20:00.000Z",
"updatedAt": "2026-09-03T18:27:30.000Z"
}
]
}
path is workspace-relative with forward slashes so it works across machines;
line is 0-based; fingerprint is the trimmed text of the anchored line and
context a hash of its neighbours, both used to re-find the line after the file
changes. author is omitted when git has no identity configured.
Both files are watched, so hand edits and incoming commits show up live. A malformed, half-written or briefly missing file is tolerated rather than throwing away data.
Requirements and limits
- An open folder or workspace. Storage is per workspace.
- Not available in Restricted Mode or virtual workspaces (
vscode.dev, remote repositories). Tack reads and writes real files and runsgitto identify comment authors. - Branch switches can move or detach comments. The fingerprint search absorbs a lot of it; the rest is inherent to annotating code out-of-band.
- There is no way for an extension to draw a genuinely floating card on top of
the text editor — the API for it (
createWebviewTextEditorInset) is proposal-only and cannot ship. Code comments therefore use VS Code's own comment widget as their editing surface.
Upgrading
Storage moved out of .vscode/ in 5.0.0. On first run, .vscode/board.json,
.vscode/sticky-notes.json and .vscode/code-comments.json are moved into
.tack/. Nothing already in .tack/ is overwritten, and a move that fails
leaves the original untouched. Commands moved from the stickyNotes. prefix to
tack. in 4.0.0 — rebind any custom keybindings. See the
changelog.
Contributing
Issues and pull requests are welcome at github.com/anubhavpathak99/vscode-tack.
npm install
npm run watch # esbuild + tsc in watch mode
npm test # runs the suite in a real VS Code instance
Press F5 to launch the Extension Development Host.