"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)