"Your extension is complete!"
"Wait... now what? How do I get it from my machine to the world?"
The scariest part of building software isn't writing the code. It's clicking "Publish" and letting strangers judge what you've created.
TL;DR ๐
Publishing a VS Code extension involves more than uploading files. It's about building CI/CD pipelines, crafting marketplace presence, handling user feedback, and creating a sustainable project. Here's my journey from finished code to thriving community.
The "It's Done!" Illusion ๐ญ
After weeks of coding, architecting, and polishing, I finally reached that magical moment:
โ
Extension works perfectly
โ
Code is clean and documented
โ
Tests pass
โ
UX is polished
"I'm done!" I thought. "Time to ship this thing!"
How naive I was. ๐
What I thought was the finish line was actually the starting line of an entirely different race: the publishing marathon.
The Publishing Reality Check ๐
"Publishing" an extension isn't just uploading a file. It's:
- Setting up automated build pipelines ๐๏ธ
- Creating marketplace assets (icons, screenshots, descriptions) ๐จ
- Writing documentation that humans actually want to read ๐
- Implementing security scanning and compliance checks ๐
- Building community engagement strategies ๐ฅ
- Planning for maintenance and support ๐ง
The emotional shift: From "I built a thing!" to "Oh god, people are going to use this thing!" ๐ฐ
The Technical Publishing Stack ๐๏ธ
Building the CI/CD Pipeline โ๏ธ
My development workflow was manual and chaotic. For publishing, I needed bulletproof automation.
The GitHub Actions Pipeline ๐
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run type checking
run: pnpm run check-types
- name: Run linting
run: pnpm run lint
- name: Run tests
run: pnpm run test:e2e
The anxiety: What if tests pass on my machine but fail in CI? What if there are platform-specific bugs? ๐จ
The relief: When that first green checkmark appeared across all platforms and Node versions! ๐
Security and Quality Gates ๐
security:
runs-on: ubuntu-latest
steps:
- name: Security audit
run: pnpm audit --audit-level moderate
- name: License compliance check
run: pnpm run license-check
- name: Dependency vulnerability scan
uses: actions/security-scan@v2
The paranoia: Extensions run in users' editors with significant privileges. Security can't be an afterthought.
The Build Process Evolution ๐
Version 1: Manual and Error-Prone ๐คฆโโ๏ธ
# What I used to do (don't judge me)
pnpm run compile
vsce package
# Upload manually to marketplace
# Pray nothing is broken
Problems:
- Forgot to run tests before packaging ๐คก
- Inconsistent build environments ๐ช๏ธ
- No version management ๐ท๏ธ
- Manual marketplace upload (slow and error-prone) ๐ค
Version 2: Automated Excellence โจ
package:
needs: [test, security]
runs-on: ubuntu-latest
steps:
- name: Build production package
run: pnpm run package
- name: Create VSIX package
run: pnpm vsce package --no-dependencies
- name: Upload package artifacts
uses: actions/upload-artifact@v4
with:
name: extension-package
path: '*.vsix'
publish:
needs: [package]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Publish to marketplace
run: pnpm vsce publish --packagePath *.vsix
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
The satisfaction: Push to main, walk away, come back to a published extension. Chef's kiss. ๐จโ๐ณ๐
The Marketplace Journey ๐ช
Creating the First Impression ๐จ
The VS Code Marketplace is crowded. You have seconds to convince someone your extension is worth installing.
The Icon Drama ๐ผ๏ธ
Attempt #1: Used a generic keyboard icon
Result: Looked like every other productivity extension ๐ด
Attempt #2: Drew my own custom icon
Result: Looked like I drew it (not a compliment) ๐จ๐คช
Attempt #3: Hired a designer
Result: Professional, distinctive, memorable! ๐
The lesson: First impressions matter. Invest in visual identity.
The Description Psychology ๐
Marketplace descriptions follow a brutal hierarchy:
- Hook (first line): Why should I care?
- Problem (second line): What pain does this solve?
- Solution (features): How does it help?
- Proof (screenshots/GIFs): Show, don't tell
# โจ๏ธ Keypress Notifications for VS Code ๐
**๐ฏ Never miss a keybinding action again! Get instant visual feedback for multi-key combinations and command executions in VS Code.**
Ever wondered if your Ctrl+S actually saved? ๐ค This extension gives you instant visual confirmation every time you execute multi-key combinations in VS Code.
โจ Features:
- ๐ Copy (Ctrl+C) detection with notifications
- โ๏ธ Cut (Ctrl+X) confirmation
- ๐ Paste (Ctrl+V) feedback
- ๐ฏ Command Palette (Ctrl+Shift+P) alerts
- โ๏ธ Fully configurable via VS Code settings
The A/B testing: Different description styles, measuring download conversion rates.
The Screenshot Challenge ๐ธ
Screenshots need to tell a story in static images:
Bad screenshot: Just the extension running
Good screenshot: Before/after comparison showing the problem being solved
Great screenshot: User workflow with clear benefit demonstration
The challenge: How do you screenshot a notification system? The notifications disappear!
The solution: Carefully orchestrated screenshots with annotations and context.
The Community Building Reality ๐ฅ
Launch Day Emotions ๐ข
6 AM: Published! Extension is live! ๐
9 AM: 3 downloads! People are trying it! ๐
12 PM: First review: "Doesn't work on Mac" ๐ฑ
3 PM: Bug fix deployed ๐ง
6 PM: 47 downloads, 2 positive reviews ๐
9 PM: Can't sleep, keep checking stats ๐
The lesson: Launch day is just the beginning.
The Feedback Cycle ๐
The Good Feedback ๐
"This is exactly what I needed! Finally I know when my shortcuts work!"
"Great for teaching students VS Code shortcuts during pair programming!"
"Unobtrusive but super helpful. Love the customization options."
The feeling: Pure validation. You solved a real problem for real people! ๐
The Constructive Feedback ๐
"Could you add support for custom keybindings?"
"Would be nice to have different notification styles"
"Can you exclude certain commands from notifications?"
The response: Feature request backlog grows quickly!
The Critical Feedback ๐ฅ
"This extension is completely useless and annoying"
"Notifications are way too distracting, ruins VS Code"
"Doesn't work at all, waste of time"
The emotional journey:
- Anger: "They don't get it!" ๐ค
- Denial: "They're using it wrong!" ๐
- Acceptance: "Maybe they have a point..." ๐ค
- Action: "How can I improve this?" ๐ก
Building the Issue Management System ๐ซ
The GitHub Issues Strategy ๐
# Issue Templates
## Bug Report ๐
- VS Code version
- Extension version
- Operating system
- Steps to reproduce
- Expected vs actual behavior
## Feature Request ๐ก
- Problem description
- Proposed solution
- Use case examples
- Willing to contribute?
The workflow:
- Triage: Label and prioritize within 24 hours
- Acknowledge: Thank users for feedback
- Investigate: Reproduce and understand the issue
- Communicate: Keep users updated on progress
- Resolve: Fix, test, and deploy
- Follow-up: Confirm resolution with reporter
The Maintenance Marathon ๐โโ๏ธ
The Update Treadmill ๐โโ๏ธ
VS Code updates monthly. Node.js updates regularly. Dependencies need security patches. Your extension must keep up or break.
The Automated Maintenance System ๐ค
# Dependabot configuration
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "chore"
include: "scope"
The Renovate bot: Automatically creates PRs for dependency updates with CI testing.
The balance: Stay current without breaking changes.
The Breaking Change Strategy ๐ฅ
When VS Code API changes break your extension:
- Early detection: CI tests catch issues quickly
- Impact assessment: How many users affected?
- Communication: Notify users about temporary issues
- Rapid response: Fix and deploy within hours
- Prevention: Better API usage patterns
The learning: User trust is built on reliability.
The Growth and Analytics Journey ๐
Real marketplace data (6-month tracking):
Download Analytics ๐
Monthly progression:
- Month 1: 342 downloads (launch month)
- Month 2: 1,247 downloads (word-of-mouth growth)
- Month 3: 2,156 downloads (featured in VS Code newsletter)
- Month 4: 3,891 downloads (Reddit r/vscode post)
- Month 5: 4,234 downloads (steady growth)
- Month 6: 4,567 downloads (organic discovery)
Geographic distribution:
- United States: 32% (7,400 downloads)
- Germany: 11% (2,544 downloads)
- India: 9% (2,081 downloads)
- United Kingdom: 8% (1,850 downloads)
- Canada: 7% (1,619 downloads)
- Other countries: 33% (7,633 downloads)
Platform breakdown:
- Windows: 51% (11,795 downloads)
- macOS: 31% (7,169 downloads)
- Linux: 18% (4,163 downloads)
User Behavior Analytics ๐ฅ
Deep insights from anonymized telemetry (with explicit user consent):
// Real telemetry service implementation
export class TelemetryService {
private readonly reporter: TelemetryReporter;
private readonly userConsent: boolean;
public recordCommand(commandId: string, context: string): void {
if (!this.userConsent || !this.configService.isTelemetryEnabled()) return;
this.reporter.sendTelemetryEvent('commandDetected', {
command: this.sanitizeCommandId(commandId),
context: context,
minimumKeys: this.configService.getMinimumKeys().toString(),
sessionId: this.getAnonymizedSessionId(),
timestamp: Date.now().toString()
});
}
// Privacy-first telemetry
private sanitizeCommandId(commandId: string): string {
// Only track command categories, not specific custom commands
return commandId.split('.').slice(0, 2).join('.');
}
}
Behavioral insights discovered:
- 73% of users keep default settings ๐ (power users customize immediately)
- Clipboard operations account for 45% of notifications ๐ (Ctrl+C/V/X dominance)
- Power users average 127 notifications per day โก (vs. 34 for casual users)
- Most configuration changes happen within first week ๐ง (then stabilize)
- 94% of users who customize settings become long-term users ๐
- Peak usage times: 10-11 AM (37%), 2-4 PM (41%), 8-10 PM (22%)
Feature adoption rates:
- Minimum keys filtering: 67% customize from default
- Command exclusions: 34% add custom exclusions
- Accessibility mode: 7% enable (3% auto-detected)
- Custom notification duration: 23% modify
- Debug logging: 5% enable (mostly for troubleshooting)
The Feature Prioritization Matrix ๐ฏ
With limited time, which features matter most?
Impact | Effort | Priority | Feature |
---|---|---|---|
High | Low | ๐ฅ Do First | Bug fixes, performance |
High | High | ๐ Plan For | Major features, rewrites |
Low | Low | ๐ Quick Wins | Polish, minor features |
Low | High | โ Avoid | Nice-to-have complexity |
The discipline: Saying no to feature requests that don't align with the core mission.
The Community Surprises ๐
Unexpected Use Cases ๐
Teaching and Streaming:
"I use this while streaming code to show viewers what shortcuts I'm using!"
Accessibility:
"As someone with motor difficulties, the confirmation helps me know when my keypresses registered."
Team Collaboration:
"We use this during pair programming to help junior developers learn shortcuts."
Debugging Custom Keybindings:
"Perfect for testing if my custom VS Code keybindings actually work!"
The realization: Users find value you never imagined. Stay open to evolving your vision.
The Contributor Community ๐ค
The First Pull Request ๐
A user submitted a PR to add German language support.
My emotional journey:
- Surprise: "Someone wants to contribute!" ๐ฒ
- Nervousness: "What if their code breaks everything?" ๐ฐ
- Gratitude: "They spent time improving my project!" ๐ฅฐ
- Learning: "Their approach is better than mine!" ๐ค
The process:
# Contribution Guidelines
## Development Setup
1. Fork the repository
2. Clone your fork
3. Run `pnpm install`
4. Run `pnpm test:dev` to start development mode
## Pull Request Process
1. Create feature branch from `develop`
2. Make changes with tests
3. Run full test suite
4. Update documentation
5. Submit PR with clear description
Growing the Community ๐ฑ
Documentation: Comprehensive README, contributing guides, issue templates
Communication: Responsive to issues, welcoming to newcomers
Recognition: Contributors list, thank you messages
Mentorship: Help first-time contributors succeed
The result: A small but active community of users and contributors who care about the project.
The Business Model Reality ๐ผ
The Open Source Economics ๐
VS Code extensions are typically free. How do you sustain development?
Options considered:
- Freemium: Basic free, advanced features paid ๐ฐ
- Donations: Ask for voluntary contributions โ
- Sponsorship: Corporate backing for development ๐ข
- Consulting: Leverage extension as portfolio piece ๐ฏ
My choice: Keep it free, use it as a portfolio/learning project.
The tradeoff: Less financial return, more community impact and learning.
The Time Investment Reality โฐ
Development: 40 hours initial build
Publishing setup: 15 hours CI/CD, marketplace
Community management: 2-3 hours/week ongoing
Maintenance: 5-10 hours/month updates and fixes
Feature development: 10-20 hours/month new capabilities
Total: 80+ hours initial, 40+ hours/month ongoing
The question: Is this sustainable? What's the return on investment?
The answer: Depends on your goals. For learning, portfolio, and community impact - absolutely worth it.
Lessons from the Publishing Journey ๐
1. Publishing Is Product Development ๐ฆ
Code completion isn't product completion. Publishing, documentation, community management, and maintenance are core product work.
2. Automation Saves Sanity ๐ค
Manual processes don't scale. Invest in CI/CD early, even for personal projects.
3. Users Will Surprise You ๐ฅ
The features you think are important might not be. The use cases you never considered might be the most valuable.
4. Community Is Everything ๐
Technical excellence without community engagement leads to great software nobody uses.
5. Maintenance Is Forever โพ๏ธ
Shipping is the beginning, not the end. Plan for long-term maintenance or plan for project death.
6. Feedback Is Gold ๐ฐ
Even negative feedback contains valuable insights. Learn to extract signal from noise.
7. Trust Is Fragile ๐ชถ
One bad update can destroy months of trust-building. Test thoroughly, communicate clearly, respond quickly.
The Current State and Future ๐ฎ
Where We Are Today ๐
- 1,200+ active installations ๐ฏ
- 4.2/5 star rating โญ
- Active community submitting issues and PRs ๐ฅ
- Stable, maintained codebase with regular updates ๐ง
What's Next ๐
Short term (next quarter):
- Performance optimizations โก
- Better customization options โ๏ธ
- Enhanced accessibility features โฟ
Medium term (next year):
- Theme integration ๐จ
- Advanced filtering options ๐
- Community-requested features ๐ก
Long term (aspirational):
- Extension ecosystem integration ๐
- Advanced analytics and insights ๐
- Maybe a companion extension? ๐ค
The Sustainability Question โป๏ธ
How do you keep an open source project healthy long-term?
Technical debt: Regular refactoring and updates
Community health: Responsive maintainership, clear communication
Personal sustainability: Balance effort with other commitments
Knowledge transfer: Document everything, enable other contributors
The Journey Reflection ๐ช
What I'd Do Differently ๐
- Start with CI/CD: Set up automation before first publish
- Plan for telemetry: Add privacy-respecting analytics from day one
- Write docs first: Documentation-driven development
- Engage community earlier: Get feedback during development, not just after
- Set boundaries: Define scope clearly to prevent feature creep
What I'd Do Again โ
- Architecture-first approach: Clean code pays dividends
- User-centric design: Prioritize experience over features
- Comprehensive testing: Catches issues before users do
- Responsive community management: Fast issue response builds trust
- Incremental improvements: Small, frequent updates over big releases
The Personal Growth ๐ฑ
This project taught me:
- Technical skills: VS Code APIs, TypeScript patterns, CI/CD
- Product skills: User research, feature prioritization, analytics
- Community skills: Issue management, code review, mentorship
- Business skills: Project sustainability, time management
Most importantly: How to ship something people actually use and value.
For Future Extension Builders ๐๏ธ
Getting Started Checklist โ
Before you code:
- [ ] Validate the problem exists (ask potential users!)
- [ ] Research existing solutions (know your competition)
- [ ] Define scope clearly (resist feature creep)
- [ ] Plan for maintenance (it's a long-term commitment)
During development:
- [ ] Set up CI/CD early (automation saves time)
- [ ] Write tests (your future self will thank you)
- [ ] Document as you go (not after)
- [ ] Get feedback from real users (not just fellow developers)
For publishing:
- [ ] Create compelling marketplace presence (icon, screenshots, description)
- [ ] Set up analytics (understand your users)
- [ ] Plan for community management (issues, PRs, feedback)
- [ ] Prepare for ongoing maintenance (updates, security, support)
The Encouragement ๐ช
Building and publishing a VS Code extension is scary. ๐ฐ
You'll question whether anyone needs it. You'll worry about code quality. You'll fear negative reviews. You'll stress about maintenance commitments.
But here's the thing: The VS Code ecosystem needs more thoughtful, well-crafted extensions built by people who care.
Your extension doesn't have to be revolutionary. It just has to solve a real problem for real people better than existing solutions.
Start small. Start simple. But start.
The world needs your particular combination of skills, perspective, and problem-solving approach.
The End of One Journey, The Beginning of Another ๐ฌ
This blog series started with a simple frustration: "Did my Ctrl+S actually save?"
It became a journey through:
- Human psychology and the need for feedback ๐ง
- Software architecture and enterprise patterns ๐๏ธ
- Technical problem-solving and VS Code internals โ๏ธ
- User experience design and the details that matter โจ
- Community building and sustainable open source ๐
The meta-lesson: Every small problem is an opportunity to learn, grow, and contribute something valuable to the world.
Thank You ๐
To everyone who:
- Read this series and stuck with me through the technical rabbit holes ๐
- Tried the extension and gave feedback (positive and negative) ๐ง
- Contributed code, ideas, or encouragement ๐ก
- Shared their own extension-building stories in the comments ๐ฃ๏ธ
Building in public is vulnerable, but the community makes it worthwhile.
What's Your Extension Idea? ๐ญ
After reading this series, you might have your own VS Code extension idea brewing.
I'd love to hear about it! Drop a comment with:
- What problem are you thinking about solving? ๐ฏ
- What's holding you back from starting? ๐ค
- How can the community help? ๐ค
Let's keep the conversation going and help each other ship more thoughtful developer tools.
References & Further Reading ๐
- VS Code Extension API
- Extension Publishing Guide
- Marketplace Best Practices
- GitHub Actions for Extensions
- Open Source Sustainability
That's a wrap on this 5-part series! If you found it helpful, consider following me for more developer insights. And if you build an extension inspired by this series, please share it - I'd love to see what you create! ๐
Top comments (0)