A modern, high-performance photo gallery platform for photographers
Official SaaS • Documentation • Live Examples • Self-Hosting
Afilmory (/əˈfɪlməri/, "uh-FIL-muh-ree") is a comprehensive photo gallery solution that combines Auto Focus (AF), Aperture (light control), Film (vintage medium), and Memory (captured moments). Built with React + TypeScript, it offers automatic photo synchronization from multiple storage sources, high-performance WebGL rendering, and professional EXIF metadata display.
👉 Get Started at afilmory.art - Zero setup, live in minutes!
The easiest way to create your photo gallery. No deployment, no servers, no maintenance required.
Why Choose SaaS?
- ✅ Zero Configuration - Sign up and go live immediately
- ✅ Live CMS - Edit photos, titles, and metadata in real-time
- ✅ Custom Domains - Bind your own domain with DNS verification
- ✅ Auto Updates - Always running the latest features
- ✅ Managed Infrastructure - We handle scaling, backups, and maintenance
For developers who need full control over their deployment:
Docker (Recommended)
# See our Docker deployment guide
https://github.com/Afilmory/dockerManual Installation
# 1. Clone and install
git clone https://github.com/Afilmory/Afilmory.git
cd Afilmory
pnpm install
# 2. Configure
cp config.example.json config.json
cp builder.config.default.ts builder.config.ts
# Edit both files with your settings
# 3. Build manifest and thumbnails
pnpm run build:manifest
# 4. Start the application
pnpm devFor detailed self-hosting instructions, see DEVELOPMENT.md and Documentation.
See Afilmory in action:
- afilmory.innei.in - Creator's personal gallery
- gallery.mxte.cc
- photography.pseudoyu.com
- afilmory.magren.cc
- 🖼️ High-Performance WebGL Renderer - Custom WebGL image viewer with smooth zoom, pan, and gesture support
- 📱 Responsive Masonry Layout - Powered by Masonic, adapts seamlessly to any screen size
- 🎨 Modern UI/UX - Built with Tailwind CSS and Radix UI for accessibility and aesthetics
- ⚡ Incremental Sync - Smart change detection processes only new or modified photos
- 🌐 Internationalization - Multi-language support with i18next
- 🔗 Social Sharing - OpenGraph metadata for rich social media previews
- 🔄 Format Support - Automatic conversion of HEIC/HEIF and TIFF formats
- 🖼️ Smart Thumbnails - Multi-size thumbnail generation for optimized loading
- 📊 Complete EXIF Display - Camera model, focal length, aperture, ISO, and more
- 🌈 Blurhash Placeholders - Elegant progressive loading experience
- 📱 Live Photos - Detection and display of iPhone Live Photos
- ☀️ HDR Images - Full HDR image support
- 🎛️ Fujifilm Recipes - Display Fujifilm film simulation settings
- 🗂️ Multi-Storage Support - S3-compatible storage, GitHub, Eagle, and local file system
- 🏷️ File System Tags - Auto-generated tags based on directory structure
- ⚡ Concurrent Processing - Multi-process/multi-thread support for fast builds
- 🗺️ Interactive Map - Geographic visualization with GPS coordinates using MapLibre
- 🔍 Fullscreen Viewer - Immersive image viewing with gesture controls
- 📷 Share & Embed - Share images to social media or embed in your website
afilmory/
├── apps/
│ ├── web/ # React SPA (Vite + React Router 7)
│ ├── ssr/ # Next.js SSR wrapper for SEO/OG
│ ├── docs/ # Documentation site (VitePress)
├── be/ # Backend services (Hono-based)
│ ├── apps/
│ │ ├── core/ # Core API server
│ │ ├── dashboard/ # Admin dashboard backend
│ │ └── oauth-gateway/# OAuth authentication gateway
│ └── packages/
│ ├── framework/ # Hono enterprise framework
│ ├── db/ # Database schemas (Drizzle ORM)
│ ├── redis/ # Redis client
│ └── websocket/ # WebSocket gateway
├── packages/
│ ├── builder/ # Photo processing pipeline
│ ├── webgl-viewer/ # WebGL image viewer component
│ ├── ui/ # Shared UI components
│ ├── hooks/ # React hooks library
│ ├── sdk/ # API client SDK
│ ├── utils/ # Utility functions
│ └── data/ # Shared data types
└── plugins/ # Builder plugins
- React 19 - Latest React with Compiler
- TypeScript - Full type safety
- Vite - Lightning-fast build tool
- React Router 7 - Modern routing
- Tailwind CSS - Utility-first CSS framework
- Radix UI - Accessible component primitives
- Jotai - Atomic state management
- TanStack Query - Data fetching and caching
- i18next - Internationalization
- Hono - Ultra-fast web framework
- Drizzle ORM - Type-safe database toolkit
- PostgreSQL - Primary database
- Redis - Caching and pub/sub
- WebSocket - Real-time communication
- Node.js - Server-side runtime
- Sharp - High-performance image processing
- AWS SDK - S3 storage operations
- Worker Threads/Cluster - Parallel processing
- EXIF-Reader - Metadata extraction
Designed with adapter pattern for flexibility:
- S3-Compatible - AWS S3, MinIO, Backblaze B2, Alibaba Cloud OSS
- GitHub - Use GitHub repository as storage
- Eagle - Import from Eagle app library
- Local File System - For development and testing
- Node.js 18+
- pnpm 10+
- TypeScript 5.9+
# Install dependencies
pnpm install
# Copy configuration files
cp config.example.json config.json
cp builder.config.default.ts builder.config.ts
# Set up environment variables
cp .env.template .env
# Edit .env with your credentials# Development
pnpm dev # Start web + SSR
pnpm dev:be # Start backend services
pnpm --filter web dev # Web app only
pnpm --filter @afilmory/ssr dev # SSR only
# Build
pnpm build # Build production web app
pnpm build:manifest # Generate photo manifest (incremental)
pnpm build:manifest -- --force # Full rebuild
# Documentation
pnpm docs:dev # Start docs dev server
pnpm docs:build # Build documentation
# Code Quality
pnpm lint # Lint and fix
pnpm format # Format code
pnpm type-check # Type checkingconfig.json - Site presentation config:
{
"name": "My Gallery",
"title": "My Photography",
"description": "Capturing beautiful moments",
"url": "https://gallery.example.com",
"accentColor": "#007bff",
"author": {
"name": "Your Name",
"url": "https://example.com",
"avatar": "https://example.com/avatar.jpg"
},
"social": {
"github": "username",
"twitter": "username"
},
"map": ["maplibre"],
"mapStyle": "builtin",
"mapProjection": "mercator"
}builder.config.ts - Photo processing config:
import { defineBuilderConfig } from '@afilmory/builder'
export default defineBuilderConfig(() => ({
storage: {
provider: 's3',
bucket: 'my-photos',
region: 'us-east-1',
// ... other S3 settings
},
system: {
processing: {
defaultConcurrency: 10,
enableLivePhotoDetection: true,
},
observability: {
showProgress: true,
showDetailedStats: true,
},
},
}))Implement the StorageProvider interface:
import { StorageProvider } from '@afilmory/builder'
class MyStorageProvider implements StorageProvider {
async getFile(key: string): Promise<Buffer | null> {
// Your implementation
}
async listImages(): Promise<StorageObject[]> {
// Your implementation
}
// ... other required methods
}Create a plugin for the build pipeline:
import { BuilderPlugin } from '@afilmory/builder'
export const myPlugin = (): BuilderPlugin => ({
name: 'my-plugin',
async onBeforeBuild(context) {
// Pre-build hook
},
async onAfterBuild(context) {
// Post-build hook
},
})- Official Documentation - Complete guides and API reference
- Quick Start Guide - Get running in 5 minutes
- SaaS Mode - Learn about hosted galleries
- Storage Providers - Setup guides for all storage options
- Deployment Guides - Deploy to various platforms
- API Reference - Backend API documentation
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and linting (
pnpm test && pnpm lint) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Attribution Network License (ANL) v1.0 © 2025 Afilmory Team
See LICENSE for more details.
- Official SaaS - Hosted gallery service
- Documentation - Full documentation
- GitHub - Source code
- Creator's Website - Project creator
from https://github.com/Afilmory/afilmory
No comments:
Post a Comment