A modern, real-time, enterprise-grade chat application built with React, TypeScript, Tailwind CSS, and Supabase. Designed as a robust foundation for building secure, scalable, and customizable communication platforms.
(Placeholder: Replace with actual screenshot of the chat interface)
- Private Chat — Direct messages between users
- Group Chat — Team conversations with customizable channels
- File Sharing — Documents, images, videos, audio, and CAD files
- Real-time Messaging — Instant delivery via Supabase Realtime
- Typing Indicators — See when others are typing (Broadcast)
- Online Presence — Visual indicators when users are online (Presence)
- Message Replies — Reply to specific messages in threads
- Message Editing — Edit your own messages with history
- Message Deletion — Soft delete with undo capability
- Unread Counts — Badge on conversations with new messages
- Message Search — Search across all conversations
- Read Status — Automatic mark-as-read on view with receipts
- Admin Panel — Manage users and roles
- Drag & Drop Upload — Paste images, drag files into composer
- Responsive Design — Works seamlessly on desktop, tablet, and mobile
FileKiwi follows a component-driven architecture with a clear separation of concerns:
| Feature | Mode | Why |
|---|---|---|
| Messages | Postgres Changes | Persistent, RLS-protected |
| Typing | Broadcast | Ephemeral, <50ms, no DB write |
| Online Status | Presence | CRDT-based, auto-cleanup on disconnect |
| Read Status | Postgres Changes | Persisted, real-time updates |
- Single channel per conversation — one WebSocket connection handles all realtime modes
- Optimistic UI — messages appear instantly before server confirmation
- Cursor pagination —
(created_at, id)composite cursor for O(log n) message loading - Debounced typing — 3s auto-clear prevents broadcast flooding
- Worker WebSocket —
worker: trueoption prevents background tab throttling - RLS on every table — security enforced at database level
graph TD
A[Client (React/Vite)] -->|HTTPS/WSS| B(Supabase API)
B --> C[Auth Service]
B --> D[Realtime Service]
B --> E[PostgreSQL DB]
B --> F[Storage Bucket]
C --> G[RLS Policies]
D --> G
E --> G
F --> G
| Category | Technology |
|---|---|
| Framework | React 18, Vite, Astro |
| Language | TypeScript |
| Styling | Tailwind CSS |
| Backend | Supabase (PostgreSQL, Auth, Realtime, Storage) |
| Icons | Lucide React |
| Formatting | Prettier, ESLint |
| Package Manager | npm / yarn / pnpm |
| Hosting | Static hosting (Apache/Nginx/Vercel/Netlify) |
filekiwi-chat/
├── public/ # Static assets
├── supabase/
│ └── migrations/ # SQL migration files for database setup
├── src/
│ ├── components/ # Reusable UI components
│ │ ├── auth/ # Authentication forms
│ │ ├── sidebar/ # Sidebar, Search, Conversation list
│ │ ├── chat/ # Chat window, messages, composer
│ │ ├── messages/ # File cards, media players
│ │ ├── modals/ # New chat, group settings, confirm
│ │ ├── admin/ # Admin panel, user manager
│ │ └── ui/ # Base primitives (Avatar, Badge, Button, Modal)
│ ├── hooks/ # Custom React hooks (useMessages, usePresence, etc.)
│ ├── lib/ # Supabase client, auth, DB queries, storage
│ ├── pages/ # Page views (Login, Dashboard, Settings)
│ ├── types/ # TypeScript type definitions
│ ├── layouts/ # Base HTML layouts
│ └── styles/ # Global CSS
├── .env.example # Environment variable template
├── .htaccess # Apache SPA routing config
├── astro.config.mjs # Astro configuration
├── tailwind.config.js # Tailwind configuration
├── tsconfig.json # TypeScript configuration
└── package.json # Dependencies and scripts
Before you begin, ensure you have the following installed:
git clone https://github.com/your-username/filekiwi-chat.git
cd filekiwi-chatnpm install
# or
yarn install
# or
pnpm install-
Copy the example environment file:
cp .env.example .env
-
Open
.envand fill in your Supabase credentials:# Supabase Configuration # Get these from your Supabase Project Settings > API PUBLIC_SUPABASE_URL=https://your-project-id.supabase.co PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here
⚠️ Security Note: Never commit your.envfile to version control. The.gitignoreis pre-configured to exclude it. Only use theanonkey in frontend code. Never expose theservice_rolekey.
This project relies on specific database tables and Row Level Security (RLS) policies.
- Go to your Supabase project dashboard.
- Navigate to the SQL Editor.
- Run the migration files located in
supabase/migrations/in order:
| Order | File | Purpose |
|---|---|---|
| 1 | 001_create_profiles.sql |
Profiles table + auto-create trigger |
| 2 | 002_create_conversations.sql |
Conversations + members tables |
| 3 | 003_create_messages.sql |
Messages table + supabase_realtime |
| 4 | 004_create_attachments.sql |
File attachments table |
| 5 | 005_create_message_reads.sql |
Read receipts table |
| 6 | 006_create_rls_policies.sql |
Row Level Security (15 policies) |
| 7 | 007_create_indexes.sql |
Performance indexes |
| 8 | 008_create_storage_bucket.sql |
Storage bucket + RLS |
| 9 | 009_create_default_admin.sql |
Default admin account |
| 10 | 010_fix_rls_and_profiles.sql |
RLS + profiles fixes |
| 11 | 011_batch_unread_counts.sql |
Batched unread-count RPC |
| 12 | 012_p0_features.sql |
P0 features (pins, reactions, forwarding) |
| 13 | 013_last_messages_rpc.sql |
Sidebar last-message RPC (DISTINCT ON) |
-
After migrations, go to Database → Replication → supabase_realtime and ensure the
messagestable is enabled for replication.-- Run this in SQL Editor if not already done by migration 3 ALTER PUBLICATION supabase_realtime ADD TABLE messages;
Migration 009_create_default_admin.sql creates a default admin user:
| Field | Value |
|---|---|
admin@example.com |
|
| Password | admin123 |
⚠️ Important: The account is created only if it doesn't already exist. Change the password immediately after first login.
- Go to Authentication → Users → Add User in Supabase Dashboard.
- Create the first employee/user account.
- Run this SQL to make them an admin (optional):
UPDATE profiles SET role = 'admin' WHERE id = '<user-uuid>';
npm run devThe application will start at http://localhost:4321 (Astro default) or http://localhost:5173 (Vite).
To create an optimized production build:
npm run buildThe static files are generated in the dist/ directory.
You can preview the production build locally:
npm run previewFileKiwi generates static files that can be hosted on any static hosting provider.
- Run
npm run build. - Upload all files from
dist/to your web server's document root. - Ensure the included
.htaccessfile is uploaded (for Apache) to handle client-side routing.
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]location / {
try_files $uri $uri/ /index.html;
}- Connect your GitHub repository.
- Set the Build Command to
npm run build. - Set the Output Directory to
dist. - Add your environment variables in the platform dashboard.
Build and run the application using Docker:
# Build the image
docker build -t filekiwi-chat .
# Run the container
docker run -p 80:80 filekiwi-chatEnsure your environment variables are passed to the container securely.
FileKiwi uses Tailwind CSS for styling. To customize the theme:
- Edit
tailwind.config.jsto change colors, fonts, and spacing. - Modify
src/styles/global.cssfor global styles and CSS variables.
Replace the logo and default text in the relevant components (src/components/layout/, src/pages/Login.tsx).
To add new authentication providers (Google, GitHub, etc.):
- Enable the provider in your Supabase Dashboard > Authentication > Providers.
- Update the login UI in
src/components/auth/LoginForm.tsxto include the new provider button.
- RLS Policies: Always verify that your Supabase RLS policies correctly restrict data access. Test with different user roles.
- Environment Variables: Never expose service role keys in the frontend. Only use the
anonkey. - Input Sanitization: While React handles most XSS risks, always validate and sanitize file uploads and rich text inputs on the backend (via Supabase Edge Functions if needed).
- Dependencies: Regularly run
npm auditand update dependencies. - Default Credentials: Change the default admin password immediately after setup.
Issue: Messages not appearing in real-time.
- Solution: Check your Supabase Realtime settings. Ensure the
messagestable is broadcastable (enabled in Database > Replication) and your RLS policies allowSELECTfor authenticated users.
Issue: "Invalid API Key" error.
- Solution: Verify
PUBLIC_SUPABASE_ANON_KEYin your.envfile matches theanonpublickey in Supabase. Do not use theservice_rolekey.
Issue: Build fails with TypeScript errors.
- Solution: Run
npm run lintto identify specific type issues. Ensure all strict mode settings intsconfig.jsonare satisfied.
Issue: Images/Files not uploading.
- Solution: Ensure the storage bucket exists and RLS policies allow
INSERTfor authenticated users. Check the bucket name insrc/lib/storage.ts.
Contributions are welcome! Please follow these steps:
- Fork the repository.
- Create a 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.
Please read our Code of Conduct before contributing.
- Follow existing code style (Prettier/ESLint).
- Write meaningful commit messages.
- Test your changes thoroughly.
- Update documentation if necessary.
This project is licensed under the MIT License - see the LICENSE file for details.
- Supabase for the incredible backend infrastructure.
- Tailwind CSS for the styling framework.
- Lucide Icons for beautiful icons.
- Astro for the hybrid web framework.
Built with ❤️ by the ApexSofteck Team www.apexsofteck.com