Package Exports
- github-pocket-db
Readme
GitHub PocketDB 🚀
Use GitHub as a database! A PocketBase-compatible solution that stores your data as JSON files in GitHub repositories and serves files through GitHub's CDN.
🎯 Why GitHub PocketDB?
- 🆓 Free hosting for public repositories
- 🌐 Global CDN for fast file delivery via GitHub
- 📦 No backend required - pure static site hosting
- 🔄 Version controlled data and files
- 🔌 PocketBase compatible API for easy migration
- ⚡ Built-in caching for optimal performance
- 🛡️ Reliable - GitHub's 99.9% uptime SLA
🚀 Quick Start
Installation
npm install github-pocket-db
Basic Usage
import { GitHubPocketDB } from 'github-pocket-db';
// Configure your GitHub database
const db = new GitHubPocketDB({
owner: 'your-username',
repo: 'your-repo',
token: process.env.GITHUB_TOKEN, // Only needed for write operations
branch: 'main'
});
// Initialize (loads schema from GitHub)
await db.init();
// Use the familiar PocketBase API!
const records = await db.collection('users').getList(1, 50);
const user = await db.collection('users').getOne('user-id');
// Files are automatically served via GitHub CDN
console.log(user.avatar); // → https://raw.githubusercontent.com/...
📋 Migration from PocketBase
Step 1: Export Your PocketBase Data
First, backup your PocketBase schema and data:
# Your schema is already available as pb_schema.json
# Export your storage directory (already done if you have /storage folder)
Step 2: Run Migration
# Install the package
npm install github-pocket-db
# Run migration
npx github-pocket-db migrate your-username your-repo your-github-token ./pb_schema.json ./storage
# Or using environment variable
GITHUB_TOKEN=your-token npx github-pocket-db migrate your-username your-repo "" ./pb_schema.json ./storage
Step 3: Update Your Code
Replace your PocketBase imports:
// OLD
import PocketBase from 'pocketbase';
const pb = new PocketBase('https://your-pocketbase-url');
// NEW
import { GitHubPocketDB } from 'github-pocket-db';
const db = new GitHubPocketDB({
owner: 'your-username',
repo: 'your-repo'
});
await db.init();
That's it! Your existing code will work with minimal changes.
📚 API Reference
Configuration
interface GitHubDBConfig {
owner: string; // GitHub username/organization
repo: string; // Repository name
branch?: string; // Branch (default: 'main')
token?: string; // GitHub token for write operations
dataPath?: string; // Data directory (default: 'data')
storagePath?: string; // Storage directory (default: 'storage')
cacheTTL?: number; // Cache TTL in seconds (default: 300)
}
Collections API
// List records with pagination and filtering
const result = await db.collection('posts').getList(1, 20, {
sort: 'created desc',
filter: 'status = "published"'
});
// Get single record
const post = await db.collection('posts').getOne('post-id');
// Create record
const newPost = await db.collection('posts').create({
title: 'Hello World',
content: 'My first post'
});
// Update record
const updatedPost = await db.collection('posts').update('post-id', {
title: 'Updated Title'
});
// Delete record
await db.collection('posts').delete('post-id');
File Handling
// Upload files with record creation
const postWithImage = await db.collection('posts').create(
{
title: 'Post with Image',
content: 'Content here'
},
{
image: [
{
name: 'photo.jpg',
type: 'image/jpeg',
size: 150000,
content: fileBuffer
}
]
}
);
// Files are automatically available via GitHub CDN
console.log(postWithImage.image[0]);
// → https://raw.githubusercontent.com/user/repo/main/storage/collection_id/record_id/photo_xyz.jpg
🏗️ Repository Structure
After migration, your repository will have this structure:
your-repo/
├── pb_schema.json # PocketBase schema definition
├── data/ # JSON data files
│ ├── users.json # User records
│ ├── posts.json # Post records
│ └── ... # Other collections
├── storage/ # File storage
│ ├── collection_id/
│ │ ├── record_id/
│ │ │ ├── file.jpg # Actual files
│ │ │ ├── file.jpg.attrs # File metadata
│ │ │ └── ...
│ │ └── ...
│ └── ...
└── your-app-files/ # Your application code
🔧 Advanced Usage
Custom Data Processing
// Access collections directly
const collections = db.getCollections();
console.log(
'Available collections:',
collections.map((c) => c.name)
);
// Clear cache when needed
db.clearAllCache();
// Custom file URL generation
const fileUrl = db.getFileURL(record, 'filename.jpg');
Read-Only Mode
For production sites, you can omit the GitHub token to run in read-only mode:
const db = new GitHubPocketDB({
owner: 'your-username',
repo: 'your-repo'
// No token = read-only mode
});
Environment Variables
# .env file
GITHUB_TOKEN=ghp_your_token_here
GITHUB_OWNER=your-username
GITHUB_REPO=your-repo
const db = new GitHubPocketDB({
owner: process.env.GITHUB_OWNER!,
repo: process.env.GITHUB_REPO!,
token: process.env.GITHUB_TOKEN
});
🔐 Security & Permissions
GitHub Token Permissions
For write operations, your GitHub token needs:
repo
scope for private repositoriespublic_repo
scope for public repositories
Read-Only Deployment
For production sites, deploy without the GitHub token for security:
- ✅ Read data from public repositories
- ✅ Serve files via GitHub CDN
- ❌ No write operations (secure)
🚀 Framework Integration
SvelteKit Example
// src/lib/db.ts
import { GitHubPocketDB } from 'github-pocket-db';
import { writable } from 'svelte/store';
const db = new GitHubPocketDB({
owner: 'your-username',
repo: 'your-repo'
});
await db.init();
export const posts = writable([]);
export async function loadPosts() {
const result = await db.collection('posts').getList();
posts.set(result.items);
return result.items;
}
Next.js Example
// lib/db.ts
import { GitHubPocketDB } from 'github-pocket-db';
const db = new GitHubPocketDB({
owner: process.env.GITHUB_OWNER!,
repo: process.env.GITHUB_REPO!
});
export async function getPosts() {
await db.init();
return db.collection('posts').getList();
}
📊 Performance & Caching
- Automatic caching with configurable TTL
- GitHub CDN for global file delivery
- Efficient pagination for large datasets
- Minimal API calls through smart caching
// Configure cache TTL (in seconds)
const db = new GitHubPocketDB({
owner: 'user',
repo: 'repo',
cacheTTL: 600 // 10 minutes
});
🐛 Troubleshooting
Common Issues
Migration fails with "File not found"
# Ensure schema file exists
ls -la pb_schema.json
# Check file permissions
chmod 644 pb_schema.json
GitHub API rate limiting
// Add token to increase rate limits
const db = new GitHubPocketDB({
owner: 'user',
repo: 'repo',
token: process.env.GITHUB_TOKEN // Increases limits from 60 to 5000/hour
});
Files not loading
// Ensure repository is public, or use token for private repos
// GitHub raw URLs require public repos for anonymous access
🤝 Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Inspired by PocketBase for the amazing API design
- Built with Octokit for GitHub API integration
- Designed for the Jamstack and static site generation era
Made with ❤️ for developers who want simple, reliable, and free database solutions.