library-writer
Guides the creation and refactoring of software libraries using industry-standard, dependency-minimal patterns.
Install
mkdir -p .claude/skills/library-writer && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/11740" && unzip -o skill.zip -d .claude/skills/library-writer && rm skill.zipInstalls to .claude/skills/library-writer
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
This skill should be used when writing software libraries, packages, or modules following battle-tested patterns for clean, minimal, production-ready code. It applies when creating new libraries, refactoring existing ones, designing library APIs, or when clean, dependency-minimal library code is needed. Triggers on requests like "create a library", "write a package", "design a module API", or mentions of professional library development.Key capabilities
- →Write software libraries following battle-tested patterns
- →Enforce a specific entry point structure for libraries
- →Implement conditional framework loading
- →Design API configuration using simple accessors
- →Create error handling hierarchies
- →Manage dependencies with zero runtime dependencies when possible
How it works
The skill guides the creation of software libraries by enforcing a strict entry point structure, conditional framework loading, and simple configuration patterns. It also defines error handling and dependency management principles.
Inputs & outputs
When to use library-writer
- →Designing a new open-source module
- →Refactoring legacy code into a library
- →Setting up a framework-agnostic package
About this skill
Library Writer
Write software libraries following battle-tested patterns from the most successful open-source maintainers. These patterns have been proven across hundreds of libraries with billions of downloads.
Core Philosophy
Simplicity over cleverness. Zero or minimal dependencies. Explicit code over metaprogramming. Framework integration without framework coupling. Every pattern serves production use cases.
The best library is the one you don't have to think about. It should:
- Install easily
- Configure simply
- Work as expected
- Not break on upgrades
- Have obvious documentation
Entry Point Structure
Every library follows this pattern:
1. Dependencies (stdlib preferred)
2. Internal modules (relative imports)
3. Conditional framework loading (never require frameworks directly)
4. Module with config and errors
Why This Order?
- Dependencies first - Fail fast if deps are missing
- Internal modules - Load library components
- Conditional framework - Don't force framework on non-framework users
- Config and errors - Ready for use immediately
Conditional Framework Loading
Never require frameworks directly. Check if they exist first:
# Only load framework integration if framework is present
if framework_is_loaded:
load framework_integration
# This allows the library to work:
# - In framework apps (with integration)
# - In plain apps (without framework overhead)
# - In test environments (isolated)
See framework-integration.md for detailed patterns.
Configuration Pattern
Use simple accessors, not Configuration objects:
Good:
MyLib.api_key = "..."
MyLib.timeout = 30
MyLib.logger = custom_logger
Bad:
MyLib.configure do |config|
config.api_key = "..."
config.timeout = 30
config.logger = custom_logger
end
Why Simple Accessors?
- Easier to understand (just assignment)
- Can be set from anywhere
- No DSL to learn
- Works with environment variables naturally
- Testable (just set the value)
Configuration Defaults
Set sensible defaults immediately:
Module MyLib:
timeout = 10 # Reasonable default
logger = null # Optional
api_key = ENV["KEY"] # From environment
See api-design.md for API patterns.
Error Handling
Simple hierarchy with informative messages:
Module MyLib:
class Error (base error)
class ConfigError (configuration problems)
class ValidationError (invalid input)
class ConnectionError (network issues)
Error Design Principles
- Inherit from standard error class - Works with existing error handling
- Few error types - Don't create an error for every situation
- Informative messages - Include what went wrong and how to fix it
- Validate early - Raise ArgumentError on bad input immediately
Good error message:
"API key must be 32 characters, got 16. Set MyLib.api_key or MYLIB_API_KEY environment variable."
Bad error message:
"Invalid key"
API Design Principles
Class Macro Pattern
The signature pattern for libraries that enhance classes:
Usage:
class Product:
searchable(fields: ["name", "description"])
Implementation:
def searchable(**options):
validate_options(options)
store_options(options)
add_methods()
Single Configuration Method
One method call should configure everything:
Good:
class User:
authenticatable() # Adds all auth methods
Bad:
class User:
add_password_field()
add_session_methods()
add_remember_token()
configure_encryption()
See api-design.md for detailed patterns.
Dependency Management
Zero Runtime Dependencies (When Possible)
Good:
# Use stdlib for common operations
# Vendor small utilities if needed
# No runtime dependencies in manifest
Bad:
# Dependencies for things stdlib handles
# Dependencies for "convenience"
# Dependencies that pull in more dependencies
Development Dependencies
Keep development dependencies separate:
Development only:
- Test framework
- Linting tools
- Documentation generators
- Debug utilities
Never in production:
- These don't ship with the library
- Users don't install them
Lock Files
Never commit lock files in libraries. Lock files:
- Lock to specific versions you tested with
- Prevent users from getting compatible updates
- Cause conflicts with user's other dependencies
See module-organization.md for structure patterns.
Testing Philosophy
Use Standard Test Framework
Every language has a standard test framework. Use it.
Python: pytest or unittest
JavaScript: Jest or Vitest
Go: testing stdlib
Rust: built-in test
Ruby: Minitest
What to Test
1. Public API - Every public method
2. Edge cases - Empty input, null, large data
3. Error conditions - Invalid input, network failures
4. Configuration - Different config combinations
5. Integration - With frameworks (if applicable)
Test Structure
tests/
├── unit/ # Fast, isolated tests
├── integration/ # Tests with external systems
└── fixtures/ # Test data
See testing-patterns.md for detailed patterns.
Anti-Patterns to Avoid
| Pattern | Problem | Alternative |
|---|---|---|
| Dynamic method generation | Hard to understand, debug | Define methods explicitly |
| Configuration objects | Unnecessary complexity | Simple accessors |
| Tight framework coupling | Limits library usage | Conditional loading |
| Many runtime dependencies | Bloat, conflicts, security | Use stdlib, vendor |
| Heavy DSLs | Learning curve, magic | Explicit method calls |
| Metaprogramming magic | Debugging nightmare | Clear, explicit code |
| Committing lock files | Version conflicts | Let users manage deps |
Directory Structure
my-library/
├── lib/ # Source code (or src/)
│ ├── my_library.ext # Entry point
│ ├── my_library/ # Internal modules
│ │ ├── client.ext
│ │ ├── config.ext
│ │ └── errors.ext
│ └── my_library/integrations/ # Framework integrations
│ └── framework.ext
├── tests/ # Test files
├── README.md # Documentation
├── LICENSE # License file
└── [package manifest] # package.json, setup.py, etc.
See module-organization.md for detailed structure.
Reference Files
For deeper patterns, see:
| File | Topics |
|---|---|
| module-organization.md | Directory layouts, file structure, require/import patterns |
| framework-integration.md | Conditional loading, hooks, lazy initialization |
| testing-patterns.md | Multi-version testing, CI setup, fixture patterns |
| api-design.md | Public interface design, class macros, configuration |
Success Criteria
A well-designed library:
- Installs with one command
- Configures with simple assignment
- Works without framework (if applicable)
- Has zero or minimal dependencies
- Uses explicit, readable code
- Tests pass across supported versions
- Documents the public API clearly
- Handles errors informatively
- Doesn't break on upgrades
When not to use it
- →When creating a library that requires many runtime dependencies
- →When a library needs to commit lock files
- →When a library uses dynamic method generation or heavy DSLs
Limitations
- →The skill emphasizes zero or minimal runtime dependencies.
- →It advises against committing lock files in libraries.
- →It discourages dynamic method generation and heavy DSLs.
How it compares
This skill prioritizes simplicity, minimal dependencies, and explicit code over metaprogramming, unlike approaches that might introduce complex configuration objects or tight framework coupling.
Compared to similar skills
library-writer side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| library-writer (this skill) | 0 | 5mo | No flags | Advanced |
| software-architecture | 333 | 6mo | No flags | Intermediate |
| codex | 32 | 2mo | Review | Advanced |
| game-development | 70 | 6mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by diegosouzapw
View all by diegosouzapw →You might also like
software-architecture
davila7
Guide for quality focused software architecture. This skill should be used when users want to write code, design architecture, analyze code, in any case that relates to software development.
codex
Lucklyric
Invoke Codex CLI for complex coding tasks requiring high reasoning capabilities. This skill should be invoked when users explicitly mention "Codex", request complex implementation challenges, advanced reasoning, or need high-reasoning model assistance. Automatically triggers on codex-related requests and supports session continuation for iterative development.
game-development
davila7
Game development orchestrator. Routes to platform-specific skills based on project needs.
senior-fullstack
davila7
Comprehensive fullstack development skill for building complete web applications with React, Next.js, Node.js, GraphQL, and PostgreSQL. Includes project scaffolding, code quality analysis, architecture patterns, and complete tech stack guidance. Use when building new projects, analyzing code quality, implementing design patterns, or setting up development workflows.
command-name
anthropics
This skill should be used when the user asks to "create a plugin", "scaffold a plugin", "understand plugin structure", "organize plugin components", "set up plugin.json", "use ${CLAUDE_PLUGIN_ROOT}", "add commands/agents/skills/hooks", "configure auto-discovery", or needs guidance on plugin directory layout, manifest configuration, component organization, file naming conventions, or Claude Code plugin architecture best practices.
python-project-structure
wshobson
Python project organization, module architecture, and public API design. Use when setting up new projects, organizing modules, defining public interfaces with __all__, or planning directory layouts.