A modern HTML-native preprint server for academic research documents. Built with FastAPI, Scroll Press accepts research from any authoring tool that produces HTML—Typst, Quarto, MyST, Jupyter, or handwritten HTML. Format freedom, instant publication, permanent URLs.
Governance: Press is fully community-owned—open source, community contributions accepted, roadmap driven by community needs, forever free. Supported by community donations and academic grants.
- HTML-native publishing: Upload complete HTML documents with embedded CSS and JavaScript
- Session-based authentication: Secure user registration and login system with email verification
- Email verification: Token-based email verification with password reset functionality
- GDPR compliance: Data export endpoint for user data portability (Article 20)
- Subject categorization: Organize research by academic disciplines
- Draft and publish workflow: Save drafts and publish when ready
- Scroll cards: Browse recent submissions with rich metadata
- Responsive design: Clean, academic-focused UI with HTMX interactions
- Performance optimized: Static file caching with CDN-ready headers
- Python 3.11+
- PostgreSQL database
- uv package manager
justto run common commands
-
Clone the repository
git clone <repository-url> cd press
-
Set up environment
cp .env.example .env # Edit .env with your database URL, port, and email service credentialsRequired environment variables:
DATABASE_URL: PostgreSQL connection stringPORT: Server port (default: 7999)RESEND_API_KEY: API key for Resend email service (for email verification)FROM_EMAIL: Email address to send from (default: noreply@updates.aris.pub)BASE_URL: Base URL for email links (defaults to https://127.0.0.1:{PORT})
-
Install dependencies and setup
just init
-
Start the development server
just dev
Visit https://localhost:7999 to access Scroll Press (HTTPS with self-signed certificate).
app/
├── auth/ # Session-based authentication and token management
│ ├── session.py # Session handling
│ └── tokens.py # Email verification and password reset tokens
├── emails/ # Email service integration
│ ├── service.py # Resend email service
│ └── templates.py # Email HTML templates
├── models/ # SQLAlchemy database models
│ ├── user.py # User model with email verification
│ ├── token.py # Token model for verification/reset
│ ├── scroll.py # Research manuscript model
│ └── subject.py # Academic subject categorization
├── routes/ # FastAPI route handlers
├── templates/ # Jinja2 templates with component macros
│ └── auth/ # Authentication templates (login, register, verify, reset)
└── database.py # Async database configuration
static/
├── css/ # Stylesheet
└── images/ # Static assets
tests/ # Comprehensive test suite
- Backend: FastAPI with async/await patterns
- Database: PostgreSQL with SQLAlchemy 2.0 async
- Authentication: Session-based with in-memory storage and token-based email verification
- Email Service: Resend API for transactional emails (verification, password reset)
- Frontend: Jinja2 templates with HTMX for dynamic interactions
- Security: HTTPS-only development with self-signed certificates
- Testing: pytest with asyncio support, parallel execution, and Playwright e2e tests
- Database Setup & Models - Database configuration, migrations, and data models
- Authentication - Session management, email verification, and security
- GDPR Compliance - Data export and privacy features
- Testing - Unit, integration, and E2E testing guide
- Deployment - Production deployment instructions
- Backup Setup - Database backup configuration
- Run all checks:
just check(includes lint, unit tests, and e2e tests) - Follow existing patterns: Session-based auth, macro components, async/await
- Write tests: All new features should include test coverage
- Read the docs: See Testing Guide for testing best practices
Contributions are welcome! Please open an issue to discuss major changes before submitting a PR.
This project is licensed under the MIT License - see the LICENSE file for details.
For issues and questions, please use the GitHub issue tracker.