Welcome to Steel Browser! 🎉 We're excited that you're interested in contributing to our open-source browser API. This guide will help you get started and make your first contribution.
- Node.js: Version 22 or higher
- npm: Version 10 or higher
- Docker: For containerized development (optional but recommended)
- Git: For version control
- Chrome/Chromium: Required for browser automation
-
Fork and Clone
git clone https://github.com/steel-dev/steel-browser.git cd steel-browser -
Install Dependencies
npm install
-
Start Development Environment
# Start both API and UI in development mode npm run dev # Or start individually: npm run dev -w api # API server on http://localhost:3000 npm run dev -w ui # UI server on http://localhost:5173
-
Verify Setup
- API: Visit http://localhost:3000/documentation
- UI: Visit http://localhost:5173
- Test REPL:
cd repl && npm start
# Build and run with Docker Compose
docker-compose -f docker-compose.dev.yml up --build
# Or use production images
docker-compose upsteel-browser/
├── api/ # Backend API (Fastify + Puppeteer)
│ ├── src/
│ │ ├── modules/ # API modules (actions, sessions, etc.)
│ │ ├── plugins/ # Fastify plugins
│ │ ├── services/ # Core services (CDP, file, session)
│ │ └── types/ # TypeScript type definitions
│ └── extensions/ # Browser extensions (must pass name as param to session creation)
├── ui/ # Frontend UI (React + Vite)
│ └── src/
│ ├── components/ # Reusable UI components
│ ├── containers/ # Page containers
│ └── contexts/ # React contexts
├── repl/ # Interactive REPL for testing
└── docs/ # Documentation
Steel Browser follows a plugin-based architecture:
-
Steel Browser Plugin (
api/src/steel-browser-plugin.ts)- Registers all the necessary services, routes, and hooks
- Can be used as a standalone plugin or integrated into your own application
- Provides the core functionality of Steel Browser
-
CDP Service (
api/src/services/cdp/cdp.service.ts)- Manages Chrome DevTools Protocol connections
- Handles browser lifecycle and page management
- Supports plugin system for extensibility
-
CDP Plugin System (
api/src/services/cdp/plugins/)- BasePlugin: Abstract base class for all plugins
- PluginManager: Manages plugin lifecycle and events
- Plugins can hook into browser events (launch, page creation, navigation, etc.)
-
Session Management (
api/src/services/session.service.ts)- Manages browser sessions and their state
- Handles session persistence and cleanup
-
File Storage (
api/src/services/file.service.ts)- Manages file uploads, downloads, and storage
- Supports session-scoped file management
import Fastify from 'fastify';
import steelBrowserPlugin, { SteelBrowserConfig } from './api/src/steel-browser-plugin.js';
const fastify = Fastify({ logger: true });
// Register Steel Browser plugin with configuration
const config: SteelBrowserConfig = {
fileStorage: {
maxSizePerSession: 100 * 1024 * 1024, // 100MB
},
customWsHandlers: [
// Your custom WebSocket handlers
],
};
await fastify.register(steelBrowserPlugin, config);
// Your additional routes and plugins
await fastify.register(myCustomPlugin);
await fastify.listen({ port: 3000 });The SteelBrowserConfig interface allows you to customize:
- fileStorage: Configure file storage limits per session
- customWsHandlers: Add custom WebSocket handlers for real-time features
Using the CDP Plugin System, you can create plugins that hook into browser lifecycle events:
import { BasePlugin, PluginOptions } from './api/src/services/cdp/plugins/core/base-plugin.js';
import { Browser, Page } from 'puppeteer-core';
export class MyCustomPlugin extends BasePlugin {
constructor(options: PluginOptions) {
super({ name: 'my-custom-plugin', ...options });
}
async onBrowserLaunch(browser: Browser): Promise<void> {
this.cdpService?.logger.info('Custom plugin: Browser launched');
// Your custom logic here
}
async onPageCreated(page: Page): Promise<void> {
this.cdpService?.logger.info('Custom plugin: New page created');
// Handle new page creation
await page.setUserAgent('MyCustomBot/1.0');
}
async onPageNavigate(page: Page): Promise<void> {
// Handle page navigation
const url = page.url();
this.cdpService?.logger.info(`Custom plugin: Navigated to ${url}`);
}
async onBrowserClose(browser: Browser): Promise<void> {
// Cleanup when browser closes
this.cdpService?.logger.info('Custom plugin: Browser closed');
}
async onShutdown(): Promise<void> {
// Cleanup when service shuts down
this.cdpService?.logger.info('Custom plugin: Service shutting down');
}
}
// Register the plugin
fastify.cdpService.registerPlugin(new MyCustomPlugin({}));The BasePlugin class provides these lifecycle hooks:
onBrowserLaunch(browser): Called when browser instance startsonPageCreated(page): Called when a new page is createdonPageNavigate(page): Called when a page navigates to a new URLonPageUnload(page): Called when a page is about to unloadonBeforePageClose(page): Called before a page is closedonBrowserClose(browser): Called when browser instance closesonShutdown(): Called during service shutdownonSessionEnd(sessionConfig): Called when a session ends
feature/description- New featuresfix/description- Bug fixesdocs/description- Documentation updatesrefactor/description- Code refactoringtest/description- Test additions/updates
We use Conventional Commits:
type(scope): description
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks
Examples:
feat(api): add session timeout configuration
fix(ui): resolve session list refresh issue
docs: update plugin development guide
test(api): add CDP service unit tests
We use automated formatting and linting:
# Format code (API)
npm run pretty -w api
# Lint code (UI)
npm run lint -w ui
# These run automatically on commit via HuskyStyle Guidelines:
- Use TypeScript for all new code
- Follow existing patterns and conventions
- Add JSDoc comments for public APIs
- Use descriptive variable and function names
- Keep functions small and focused
Note: We're currently building out our test suite! This is a great area for contributions.
# Tests are currently being set up - for now run these checks:
npm run build # Type checking for both API and UI
npm run lint -w ui # UI linting
npm run pretty -w api # API code formatting
# When tests become available:
# npm test -w api
# npm test -w uiTesting Guidelines:
- Write unit tests for new functions and classes
- Add integration tests for API endpoints
- Include end-to-end tests for critical user flows
- Mock external dependencies appropriately
- Aim for meaningful test coverage, not just high percentages
-
Create an Issue (for non-trivial changes)
- Describe the problem or feature request
- Discuss the approach with maintainers
- Reference the issue in your PR
-
Test Your Changes
# Build and test locally npm run build # npm test # tests coming soon # Test with Docker docker-compose -f docker-compose.dev.yml up --build
-
Update Documentation
- Update relevant README sections
- Add/update JSDoc comments
- Update API documentation if needed
- Branch is up-to-date with main
- Code follows project style guidelines
- Tests pass (when available)
- Documentation is updated
- Commit messages follow conventional format
- PR description clearly explains changes
- Breaking changes are documented
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Tested locally
- [ ] Added/updated tests
- [ ] Tested with Docker
## Related Issues
Fixes #(issue number)Use our bug report template and include:
- Clear description of the issue
- Steps to reproduce
- Expected vs actual behavior
- Environment details (OS, Node version, etc.)
- Screenshots/logs if applicable
- Check existing issues first
- Describe the use case and motivation
- Provide examples of how it would work
- Consider implementation complexity
Looking for ways to contribute? Check out issues labeled:
good first issue- Perfect for newcomershelp wanted- We'd love community helpdocumentation- Improve our docstesting- Help build our test suite
- API Documentation
- Steel Cookbook - Usage examples
- Discord Community - Get help and discuss
We are committed to providing a welcoming and inclusive environment for all contributors. Please:
- Be respectful and constructive in discussions
- Help newcomers and answer questions
- Provide helpful feedback in code reviews
- Report any unacceptable behavior to maintainers
- Discord: Join our Discord server for real-time help
- GitHub Issues: For bug reports and feature requests
- GitHub Discussions: For questions and general discussion
We appreciate all contributions! Contributors are recognized:
- In our README contributors section
- In our Discord server + Changelog announcements
- Through GitHub's contribution tracking
- In release notes for significant contributions
- Potential invitation to join the core team
Key environment variables for development:
# API Configuration
NODE_ENV=development
HOST=0.0.0.0
PORT=3000
CHROME_HEADLESS=false # For debugging
ENABLE_CDP_LOGGING=true # For detailed logs
# UI Configuration
API_URL=http://localhost:3000# Debug API with Chrome DevTools
node --inspect ./api/build/index.js
# Debug with VS Code
# Use the provided launch configurations
# Enable verbose logging
ENABLE_VERBOSE_LOGGING=true npm run dev -w api- Use clear, concise language
- Include code examples
- Add screenshots for UI features
- Keep examples up-to-date
- Follow markdown best practices
- README.md: Project overview and quick start
- CONTRIBUTING.md: This file - contribution guidelines
- API docs: Auto-generated from OpenAPI schemas
- Architecture docs: High-level system design
- Plugin docs: Plugin development guides
We use automated semantic versioning based on conventional commits:
-
Automatic Version Bumping: Versions are automatically bumped based on commit messages
patch: Commits withpatch,fix,fixes, ordocsminor: Commits withfeat,feature, orminormajor: Commits withbreaking,breaking-change, ormajor
-
Beta Releases: All releases are tagged with
-betasuffix initially -
Automatic Changelog: Generated from commit history with categorized changes
-
GitHub Releases: Automatically created with changelog and community links
We follow Semantic Versioning:
- MAJOR: Breaking changes (triggered by
breaking,breaking-change,majorin commits) - MINOR: New features, backwards compatible (triggered by
feat,feature,minor) - PATCH: Bug fixes, backwards compatible (triggered by
patch,fix,fixes,docs)
The release process is fully automated via GitHub Actions:
- Push to main: Any push to the main branch triggers the release workflow
- Version bump: Automatically determines version based on commit messages
- Changelog generation: Creates categorized changelog from commits
- GitHub release: Creates release with changelog and community links
- Tag creation: Tags the release with the new version
If manual intervention is required:
- Ensure commit messages follow conventional format
- Push changes to main branch
- Monitor the GitHub Actions workflow
- Verify the release was created successfully
- Announce on Discord/social media
Thank you for contributing to Steel Browser! Your contributions help make browser automation more accessible and powerful for developers worldwide.
Happy hacking! 🎉