A lightweight, real-time collaborative spreadsheet application built with Next.js, TypeScript, Tailwind CSS, and Firebase. This project demonstrates real-time collaboration capabilities similar to Google Sheets, with a focus on clean architecture and modern web technologies.
- Live Demo: [https://trademarkia-collaborative-spreadshe-eight.vercel.app]
- Demo Video: [https://www.loom.com/share/d22dc99ca85b4fd3ab865a1a90fc6a75]
- GitHub Repository: https://github.com/Monkdev7/trademarkia-collaborative-spreadsheet
This project is a real-time collaborative spreadsheet editor that allows multiple users to work on the same document simultaneously. Built as part of the Trademarkia Frontend Engineering Assignment, it showcases:
- Real-time data synchronization across multiple users
- Formula evaluation engine with cell references
- Modern UI/UX with a focus on usability
- Clean architecture with TypeScript and Next.js App Router
- Firebase integration for authentication and real-time database
- Framework: Next.js 15 (App Router)
- Language: TypeScript (Strict mode)
- Styling: Tailwind CSS
- Database: Firebase Firestore
- Authentication: Firebase Authentication
- State Management: Zustand
- Deployment: Vercel
✅ Real-time Collaborative Editing - Multiple users can edit the same spreadsheet simultaneously
✅ Spreadsheet Grid - 50 rows × 26 columns with numbered rows and lettered columns
✅ Formula Support - Implements =SUM(A1:A5) and basic arithmetic operations (+, -, *, /)
✅ Presence Indicators - See active users with color-coded avatars
✅ Write-state Indicator - Visual feedback showing "Syncing..." or "All changes saved"
✅ Authentication - Google Sign-In and Guest mode with display names
✅ Document Dashboard - List all spreadsheets with title, last modified, and creator info
✅ Cell Formatting - Bold, italic, and text color formatting per cell
✅ Export Support - Export spreadsheets to CSV and JSON formats
✅ Keyboard Navigation - Arrow keys, Tab, Shift+Tab, Enter, Shift+Enter for seamless navigation
✅ Column/Row Resize - Drag to resize columns and rows with minimum constraints
✅ Column/Row Reorder - Drag-and-drop to reorder columns and rows
- Modern SaaS-style dashboard with interactive cards
- Smooth hover effects and transitions
- Purple gradient theme throughout
- Editable document titles with placeholder behavior
- Professional formatting toolbar
- Empty states and loading indicators
- Responsive design
┌─────────────────────────────────────────────────────────────┐
│ Next.js App │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ React Components (UI Layer) │ │
│ │ • Dashboard • Spreadsheet • Toolbar • Cells │ │
│ └────────────────────────────────────────────────────────┘ │
│ ↕ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ State Management (Zustand) │ │
│ │ • Auth State • Sync Status • Local Edit State │ │
│ └────────────────────────────────────────────────────────┘ │
│ ↕ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Firebase SDK (Client) │ │
│ │ • Firestore Listeners • Auth Methods │ │
│ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↕
┌─────────────────────────────────────────────────────────────┐
│ Firebase Backend │
│ ┌──────────────────────┐ ┌──────────────────────────────┐│
│ │ Firestore DB │ │ Firebase Auth ││
│ │ • documents/ │ │ • Google Provider ││
│ │ • presence/ │ │ • Anonymous Provider ││
│ └──────────────────────┘ └──────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
Next.js App Router
- Server components for better performance
- File-system based routing
- Built-in API routes (not used, Firebase handles backend)
Firebase Firestore
- Real-time listeners with
onSnapshotfor live updates - Document-based structure for spreadsheets
- Separate collection for presence tracking
State Management Strategy
- Local State: React
useStatefor component-specific state (edit mode, input values) - Client State: Zustand for auth and sync status (lightweight, no boilerplate)
- Server State: Firestore for persistent data (real-time by default)
Spreadsheet Grid Rendering
- React components for each cell
React.memoto prevent unnecessary re-renders- Local edit state to avoid re-render issues during typing
- Controlled inputs with debounced Firebase writes (500ms)
Formula Evaluation
- Custom parser supporting cell references (A1, B2) and ranges (A1:A5)
- Safe evaluation using Function constructor with controlled scope
- Single-pass evaluation to prevent circular references
The application uses Firebase Firestore's real-time listeners to enable collaborative editing:
- Document Sync: Each spreadsheet is stored as a Firestore document with a
cellsobject containing all cell data - Real-time Listeners:
onSnapshotlisteners detect changes and update the UI immediately - Optimistic Updates: UI updates instantly while changes are being saved to Firebase
- Debounced Writes: Cell updates are debounced (500ms) to reduce database operations
- Presence System: Separate Firestore collection tracks active users, updated every 5 seconds
- Conflict Resolution: Last-write-wins strategy (simple and predictable)
// Document structure in Firestore
{
id: string
title: string
lastModified: number
createdBy: string
cells: {
"A1": { value: "Hello", bold: true },
"B2": { formula: "=SUM(A1:A5)" },
"C3": { value: "123", color: "#EF4444" }
}
columnWidths: { "A": 120, "B": 150 }
rowHeights: { 1: 40, 2: 50 }
columnOrder: ["A", "B", "C", ...]
rowOrder: [1, 2, 3, ...]
}
// Presence structure
{
[userId]: {
id: string
name: string
email?: string
color: string
lastSeen: number
}
}collaborative-spreadsheet/
├── app/
│ ├── document/[id]/
│ │ └── page.tsx # Spreadsheet editor page
│ ├── layout.tsx # Root layout with metadata
│ ├── page.tsx # Dashboard with document list
│ ├── globals.css # Global styles
│ └── favicon.ico
│
├── components/
│ ├── dashboard/
│ │ ├── DeleteSpreadsheetModal.tsx
│ │ └── DocumentActionsMenu.tsx
│ ├── editor/
│ │ └── ExportMenu.tsx
│ ├── layout/
│ │ ├── Navbar.tsx # Top navigation bar
│ │ ├── PageContainer.tsx # Page wrapper component
│ │ └── UserDropdown.tsx # User menu dropdown
│ ├── spreadsheet/
│ │ └── FormattingToolbar.tsx # Cell formatting controls
│ ├── ui/
│ │ ├── Avatar.tsx # User avatar component
│ │ ├── Badge.tsx # Badge component
│ │ ├── Button.tsx # Reusable button component
│ │ ├── Card.tsx # Card component
│ │ ├── Dropdown.tsx # Dropdown component
│ │ ├── Input.tsx # Input component
│ │ └── Modal.tsx # Modal component
│ ├── AuthModal.tsx # Authentication UI
│ ├── DocumentCard.tsx # Document list item
│ ├── FormulaBar.tsx # Formula input bar
│ ├── PresenceIndicator.tsx # Active users display
│ ├── SaveStatus.tsx # Sync status indicator
│ ├── Spreadsheet.tsx # Main spreadsheet component
│ ├── SpreadsheetCell.tsx # Individual cell component
│ └── Toolbar.tsx # Editor toolbar
│
├── lib/
│ ├── colors.ts # User color palette
│ ├── export.ts # CSV/JSON export utilities
│ ├── firebase.ts # Firebase initialization
│ ├── formula-parser.ts # Formula evaluation engine
│ ├── store.ts # Zustand stores
│ └── types.ts # TypeScript interfaces
│
├── public/ # Static assets
├── .env.local # Environment variables (not in git)
├── .gitignore
├── next.config.ts
├── package.json
├── tsconfig.json
└── README.md
app/page.tsx: Dashboard listing all documentsapp/document/[id]/page.tsx: Spreadsheet editor with dynamic routingcomponents/Spreadsheet.tsx: Main spreadsheet logic, handles real-time sync, formulas, resize, reordercomponents/SpreadsheetCell.tsx: Individual cell with edit/display modes, formatting, keyboard navigationlib/formula-parser.ts: Formula evaluation engine supporting SUM and arithmeticlib/firebase.ts: Firebase configuration and initializationlib/store.ts: Zustand stores for auth and sync status
- Node.js 18+ and npm
- Firebase account
- Git
- Clone the repository
git clone https://github.com/Monkdev7/trademarkia-collaborative-spreadsheet.git
cd collaborative-spreadsheet- Install dependencies
npm install- Configure Firebase
Create a Firebase project at https://console.firebase.google.com
Enable the following services:
- Firestore Database: Create database in production mode
- Authentication: Enable Google provider and Anonymous authentication
Add Firestore security rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /documents/{document} {
allow read, write: if true;
}
match /presence/{document} {
allow read, write: if true;
}
}
}- Set up environment variables
Create a .env.local file in the root directory:
NEXT_PUBLIC_FIREBASE_API_KEY=your_api_key_here
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_project_id.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_project_id.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
NEXT_PUBLIC_FIREBASE_APP_ID=your_app_idGet these values from Firebase Console → Project Settings → General → Your apps → Web app
- Run the development server
npm run devOpen http://localhost:3000 in your browser.
- Build for production
npm run build
npm start- Open the application in two different browser windows (or use incognito mode)
- Sign in with different accounts (or one Google + one Guest)
- Create or open the same spreadsheet in both windows
- Edit cells in one window and observe real-time updates in the other
- Check presence indicators showing active users
This project is deployed on Vercel for optimal Next.js performance.
Mayank Anand
- GitHub: @Monkdev7
- Repository: trademarkia-collaborative-spreadsheet
This project was built as part of the Trademarkia Frontend Engineering Assignment. The assignment required:
- Real-time collaborative spreadsheet editor
- Formula support with cell references
- Presence system for active users
- Authentication (Google + Guest)
- Document dashboard
- Clean TypeScript code with no build errors
- Deployed on Vercel
All core requirements and bonus features have been implemented.
- Next.js team for the excellent framework
- Firebase for real-time infrastructure
- Tailwind CSS for the utility-first approach
- Vercel for seamless deployment
Built with ❤️ for Trademarkia