Skip to content

Shipped my first NPM package - meet SpeakEasy 🎤

Published: Estimated Reading Time: 4 min read 4 min read

After years of using npm packages, I finally published my first one. Meet SpeakEasy, a unified text-to-speech library that makes adding voice capabilities to applications simple.

The Problem That Started It All

Working on various projects, I found myself repeatedly implementing text-to-speech functionality. Each time, I’d have to:

The fragmentation was annoying. I wanted a single interface that could handle multiple providers with smart caching built-in. I was also seeing my credits get eaten up by repetitive generation, and there was this little nudge of latency I could do away with. Hence the cache implementation.

What SpeakEasy Does

SpeakEasy is a unified TTS library that abstracts away the complexity of working with different speech synthesis providers. For me, it also removes the need to configure every project with all my keys - I can have one thing that has all my text-to-speech keys, and every project can use it. Here’s what makes it useful:

Multiple Provider Support

Smart Caching

SpeakEasy automatically caches generated speech to avoid redundant API calls, which saves costs when dealing with repeated text.

Developer Experience

The API is intentionally simple:

import { SpeakEasy } from '@arach/speakeasy'

const speaker = new SpeakEasy({
  provider: 'openai',
  apiKey: 'your-api-key'
})

await speaker.speak('Hello, world!')

That’s it. No complex setup, no provider-specific configurations to remember.

Building It

Architecture Decisions

The key insight was treating TTS providers as interchangeable plugins with a common interface. I also wanted both an SDK for programmatic use and a CLI for quick testing and scripts. And I wanted it to be open source and easy to install. This meant:

  1. Provider abstraction - Each provider implements the same interface
  2. Dual interface - SDK for code integration, CLI for quick tasks
  3. Caching layer - Sits between the user and providers
  4. Configuration management - Unified settings across all providers
  5. Error handling - Consistent error responses regardless of provider

TypeScript

I used TypeScript for type safety and better developer experience with autocomplete and inline documentation.

Testing Strategy

I implemented comprehensive testing covering:

The Publishing Process

Publishing to npm for the first time taught me a few things:

Package Preparation

CI/CD Pipeline

I set up automated publishing using GitHub Actions, which:

What’s Next

SpeakEasy is just getting started. Some features I’m excited to add:

Lessons Learned

A few things I learned:

  1. Start simple - Don’t try to solve every problem in v1
  2. Documentation is crucial - Good docs can make or break adoption
  3. Community feedback - Early user feedback is invaluable
  4. Maintenance matters - Publishing is just the beginning

Try It Out

If you’re building something that needs text-to-speech capabilities, I’d love for you to try SpeakEasy:

npm install @arach/speakeasy

Check out the documentation for comprehensive examples and API reference.

Wrapping Up

Publishing my first npm package was a good experience and honestly pretty easy. It’s nice to contribute something back to the ecosystem.

In retrospect, I should have shipped a few more by now. If you’ve got repeated patterns in your code, consider packaging them up. The JavaScript community benefits from this kind of sharing.


Have you built something with SpeakEasy? I’d love to hear about it! Reach out on X or GitHub.