A professional-grade social media application built with React Native, TypeScript, and Supabase
Live Demo β’ Report Bug β’ Request Feature
- About
- Features
- Demo
- Tech Stack
- Getting Started
- Usage
- Project Structure
- API Reference
- Building
- Deployment
- Contributing
- License
- Contact
Framez is a feature-rich social media application that demonstrates modern mobile development best practices. Built for the HNG Internship Stage 4 challenge, it showcases professional-grade UI/UX, complete CRUD operations, real-time data synchronization, and advanced features like theme switching and search functionality.
- User-First: Intuitive navigation and natural interactions
- Performance: Optimized rendering and data fetching
- Accessibility: Clear visual hierarchy and responsive design
- Modern: Instagram-quality UI with smooth animations
-
π Secure Authentication
- Email/password signup and login
- Session persistence across app restarts
- Secure token storage with Expo SecureStore
- Password visibility toggle
-
π Dynamic Feed
- Real-time post updates with Supabase subscriptions
- Pull-to-refresh functionality
- Optimized loading states
- Beautiful empty states
-
π Powerful Search
- Real-time search as you type (300ms debounce)
- Search by post content or author name
- Recent search history (last 5 searches)
- Smart search result counter
-
β Content Creation
- Text posts with 500-character limit
- Image uploads with cloud storage
- Combined text and image posts
- Real-time character counter
- Image preview and editing
-
π€ User Profiles
- Letter-based avatar generation
- User statistics (posts, photos, followers)
- Join date display
- Personal post gallery
-
π Theme System
- Dark and light mode support
- Instant theme switching
- Persistent theme preference
- All screens adapted for both themes
-
βοΈ Comprehensive Settings
- Profile editing
- Theme customization
- Privacy policy access
- Account management
- Sign out with confirmation
-
βοΈ Post Management
- Edit your own posts
- Delete posts with confirmation
- Three-dot action menu
- Permission-based visibility
-
β¨οΈ Perfect Keyboard UX
- Tap outside to dismiss
- Scroll to dismiss
- Natural keyboard behavior
Try the app live without any downloads:
π Launch Framez on Appetize.io
Create your own account!
- π Theme Toggle: Profile β Settings β Toggle Dark Mode
- π Search: Search tab β Type to search posts
- β Create: Create tab β Share a post with image
- βοΈ Edit: Profile β Tap β― on your post β Edit
- ποΈ Delete: Profile β Tap β― on your post β Delete
- React Native - Mobile framework
- Expo - Development platform
- TypeScript - Type safety
- React Navigation - Navigation library
- React Context API - State management
- Supabase - Backend as a Service
- Authentication
- PostgreSQL Database
- Cloud Storage
- Real-time Subscriptions
- Row Level Security
{
"@react-navigation/bottom-tabs": "^6.x",
"@react-navigation/native": "^6.x",
"@react-navigation/native-stack": "^6.x",
"@supabase/supabase-js": "^2.x",
"expo-image-picker": "~14.x",
"expo-secure-store": "~12.x",
"@react-native-async-storage/async-storage": "1.x"
}- Node.js (v16 or higher)
- npm or yarn
- Expo CLI (
npm install -g expo-cli) - Supabase Account (Sign up)
- Clone the repository
git clone https://github.com/youneedgreg/framez_app.git
cd framez- Install dependencies
npm install- Set up Supabase
- Create a new project at Supabase Dashboard
- Run the SQL schema (see Database Setup)
- Create a storage bucket named
post-images(make it public)
- Copy the environment template
cp .env.example .env- Get your Supabase credentials
- Go to Supabase Dashboard
- Select your project
- Go to Settings β API
- Copy your Project URL and anon/public key
- Update
.envfile
EXPO_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
EXPO_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here.env file!
Run this SQL in your Supabase SQL Editor:
-- Create profiles table
CREATE TABLE profiles (
id UUID REFERENCES auth.users ON DELETE CASCADE PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create posts table
CREATE TABLE posts (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID REFERENCES auth.users ON DELETE CASCADE NOT NULL,
author_name TEXT NOT NULL,
content TEXT,
image_url TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Enable Row Level Security
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- Profiles policies
CREATE POLICY "Public profiles are viewable by everyone"
ON profiles FOR SELECT USING (true);
CREATE POLICY "Users can insert their own profile"
ON profiles FOR INSERT WITH CHECK (auth.uid() = id);
CREATE POLICY "Users can update their own profile"
ON profiles FOR UPDATE USING (auth.uid() = id);
-- Posts policies
CREATE POLICY "Posts are viewable by everyone"
ON posts FOR SELECT USING (true);
CREATE POLICY "Authenticated users can create posts"
ON posts FOR INSERT WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update their own posts"
ON posts FOR UPDATE USING (auth.uid() = user_id);
CREATE POLICY "Users can delete their own posts"
ON posts FOR DELETE USING (auth.uid() = user_id);# Start Expo development server
npx expo start
# Or run on specific platform
npx expo start --ios
npx expo start --android
npx expo start --webScan the QR code with Expo Go app (iOS/Android)
- Launch the app
- Tap "Sign Up"
- Enter email, name, and password
- Tap "Create Account"
Feed π - Scroll posts, pull to refresh
Search π - Type to search, view recent searches
Create β - Write posts, add images
Profile π€ - View stats, manage posts
Settings βοΈ - Toggle dark mode, edit profile
framez/
βββ src/
β βββ contexts/
β β βββ AuthContext.tsx # Authentication state
β β βββ ThemeContext.tsx # Theme state
β βββ screens/
β β βββ AuthScreen.tsx # Login/Signup
β β βββ FeedScreen.tsx # Main feed
β β βββ SearchScreen.tsx # Search
β β βββ CreatePostScreen.tsx # Create posts
β β βββ ProfileScreen.tsx # Profile
β β βββ SettingsScreen.tsx # Settings
β βββ components/
β β βββ PostCard.tsx # Post component
β βββ navigation/
β β βββ AppNavigator.tsx # Navigation
β βββ lib/
β β βββ supabase.ts # Supabase client
β βββ types/
β βββ index.ts # TypeScript types
βββ App.tsx # Root component
βββ .env # Environment variables
βββ .env.example # Environment template
βββ README.md # This file
// Sign up
await supabase.auth.signUp({
email: 'user@example.com',
password: 'password123'
});
// Sign in
await supabase.auth.signInWithPassword({
email: 'user@example.com',
password: 'password123'
});
// Sign out
await supabase.auth.signOut();// Create post
await supabase.from('posts').insert({
user_id: userId,
author_name: userName,
content: 'Post content',
image_url: 'https://...'
});
// Get all posts
await supabase
.from('posts')
.select('*')
.order('created_at', { ascending: false });
// Update post
await supabase
.from('posts')
.update({ content: 'Updated' })
.eq('id', postId);
// Delete post
await supabase
.from('posts')
.delete()
.eq('id', postId);
// Search posts
await supabase
.from('posts')
.select('*')
.or(`content.ilike.%${query}%,author_name.ilike.%${query}%`);# Install EAS CLI
npm install -g eas-cli
# Login
eas login
# Configure
eas build:configure
# Add secrets
eas secret:create --scope project --name EXPO_PUBLIC_SUPABASE_URL --value "YOUR_URL"
eas secret:create --scope project --name EXPO_PUBLIC_SUPABASE_ANON_KEY --value "YOUR_KEY"
# Build
eas build -p android --profile preview- Build APK using EAS
- Go to Appetize.io
- Upload your
.apkfile - Get your public demo link
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
Your Name - @youneedgreg
Project: github.com/youneedgreg/framez
Live Demo: appetize.io/app/your-app-id
- HNG Internship - Stage 3 Challenge
- HNG Hire - Connect with talent
- React Native, Expo, Supabase, TypeScript
- Instagram (UI/UX), Twitter (Search), Reddit (Interactions)
β Star this repo if you find it useful! β
Made with β€οΈ for HNG Internship