Time Capsule is a meaningful web application designed to preserve memories and deliver them to your future self or loved ones. Create sealed digital capsules containing messages, photos, and notes, and schedule them to be revealed at any future date.
- About
- Features
- Tech Stack
- Architecture
- Project Structure
- Screenshots
- Getting Started
- Configuration
- Security
- Database Schema
- How to Contribute?
- What's Next?
- Author
In an era of instant gratification, Time Capsule encourages slow, intentional memory keeping. Whether it's a letter to yourself one year from now, a shared memory vault for a graduating friend group, or a collection of milestones for a newborn, Time Capsule provides a secure and nostalgic way to bridge the gap between present and future.
- Scheduled Unlocking: Capsules remain strictly sealed until the user-defined unlock date.
- Custodian Network: Invite collaborators to contribute to your capsule or viewers to wait for its reveal.
- Multimedia Support: Attach text, high-quality images, and files to your memory vault.
- Smart Notifications: Receive automated email notifications the moment a capsule unlocks.
- Secure Persistence: Stateless authentication with Hybrid JWT Approach ensures your memories are for your eyes only.
- Public Vaults: Explore public time capsules shared by the owners to you.
- File Storage: Secure file storage using Amazon S3.
- File Encryption: AES-128 archival encryption applied at source node.
- Caching and Logging: Implemented caching and logging to improve performance and debugging.
- Interactive Documentation: Interactive API documentation using Swagger UI.
- Responsive Design: A fluid, glassmorphic UI optimized for both desktop and mobile.
- Framework: Next.js 14 (App Router)
- Library: React 18
- Styling: Tailwind CSS + Radix UI
- State Management: Zustand
- Forms & Validation: React Hook Form + Zod
- Icons: Hugeicons + Lucide React
- Framework: Spring Boot 3.x
- Language: Java 21
- Auth: Spring Security + JWT (Stateless)
- Database: PostgreSQL (Primary)
- ORM: Spring Data JPA + Hibernate
- Migrations: Flyway
- Storage: Amazon S3 (Scalable file storage)
- Scheduling: Spring
@Scheduledfor background job processing
The system follows a classic client-server architecture with clear separation of concerns:
time-capsule/
├── backend/ # Spring Boot Maven Project
│ ├── src/main/java/com/akshansh/timecapsulebackend/
│ │ ├── config/ # Application & Security configuration
│ │ ├── controller/ # REST Endpoints
│ │ ├── exception/ # Custom exceptions
│ │ ├── filter/ # Filters
│ │ ├── mapper/ # Mapper classes
│ │ ├── model/ # JPA Entities & DTOs
│ │ ├── repository/ # Data Access Layer
│ │ ├── security/ # Auth filter
│ │ ├── service/ # Business logic & Scheduled tasks
│ │ └── util/ # Utility classes
│ └── src/main/resources/ # App properties & Flyway scripts
└── frontend/ # Next.js Application
├── src/
│ ├── app/ # Routes & Pages
│ ├── components/ # Reusable UI components
│ ├── lib/ # API clients & Constants
│ ├── store/ # Zustand state stores
│ └── types/ # TypeScript definitions
└── tailwind.config.ts # Styling configuration- Java 21 & Maven
- Node.js 18+ & npm/pnpm
- PostgreSQL instance
- Navigate to
/backend. - Configure
.envorapplication.propertieswith your DB and SMTP credentials. - Run the application:
mvn spring-boot:run
- Navigate to
/frontend. - Install dependencies:
npm install
- Configure
.env.localwith your Backend API URL. - Start the development server:
npm run dev
spring.datasource.username= ${DB_USERNAME}spring.datasource.password= ${DB_PASSWORD}spring.datasource.url= ${DB_URL}jwt.secret-key= ${JWT_SECRET_KEY}spring.mail.username= ${MAIL_USERNAME}spring.mail.password= ${MAIL_PASSWORD}aws.bucket.name= ${S3_BUCKET_NAME}aws.accessKey= ${AWS_ACCESS_KEY}aws.secretKey= ${AWS_SECRET_KEY}resend.api.key= ${RESEND_API_KEY}resend.from.email= ${RESEND_FROM_EMAIL}
NEXT_PUBLIC_API_URL: Base URL of your backend.
- Hybrid JWT Authentication: Access tokens + Stored Refresh tokens in DB. Secure, stateless user sessions.
- Resource Privacy: Capsules are protected at the data layer; locked content is inaccessible until the unlock date passes.
- Role-Based Access: Granular control via
OWNER,CONTRIBUTOR, andVIEWERroles. - Input Sanitization: Strictly validated payloads using Zod and Spring Validation.
Contributions are welcome! Please follow these steps:
- Fork the project.
- Create your Feature Branch (
git checkout -b feature/AmazingFeature). - Commit your changes (
git commit -m 'Add some AmazingFeature'). - Push to the branch (
git push origin feature/AmazingFeature). - Open a Pull Request.
- Dockerization: Full-stack containerization for one-click deployment.
- Multimedia Player: In-app song player for audio memories.
- Advanced Filtering: Search and filter public vaults by nostalgia categories.
Akshansh
- GitHub: @akshansh029
- LinkedIn: akshanshsingh







