The Idea: Democratizing Wine Expertise with AI
After analyzing the French wine market, I identified a major problem: 73% of French people struggle to choose wine, and Millennials find this world "too complicated" and "intimidating." No French app truly combined advanced AI, simplicity, and personalized recommendations based on dishes.
The idea for SOMMIA was born: transform your smartphone into a personal sommelier that recommends the perfect wine based on your dish, budget, and preferences.
Why Bolt.new Changed Everything
The Initial Challenge
Developing a mobile app with AI as a solo founder, without a technical team, on a tight budget and a 2-week deadline. Mission impossible? Not with Bolt.new.
What Convinced Me
When I discovered that Bolt.new supported Expo and React Native, I knew this was the tool I needed. The promise was compelling: "Skip the coding bootcamp! With Bolt and Expo you can create mobile applications simply by describing the app you want to build."
The Magic Workflow
No-code to low-code: Start with natural language description then refine the code
Instant preview: Real-time testing with Expo Go
Direct App Store path: Straight to production via EAS Build
Technical Architecture with Bolt
My Initial Prompt
Create a mobile app SOMMIA with Expo and Supabase:
Wine recommendation AI app for French Millennials.
Simple interface:
- Onboarding screen (7-day free trial)
- Camera for dish photos OR text input
- Results screen with 3 wine recommendations + reasoning
- 5-star rating system
- Premium paywall €4.99/month after 7 days
- Supabase auth + Stripe subscriptions
- Modern UI, premium colors (burgundy/gold)
- Expo Router navigation
- AsyncStorage for caching
Stack: React Native + Expo + Supabase + Stripe
Design: Elegant, simple, confidence-building
// Complete structure generated by Bolt.new
src/
├── components/
│ ├── Camera.jsx // Dish photo capture
│ ├── WineCard.jsx // Recommendation display
│ ├── PaywallModal.jsx // Subscription modal
│ └── LoadingSpinner.jsx // Loading states
├── screens/
│ ├── OnboardingScreen.jsx // 7-day trial introduction
│ ├── HomeScreen.jsx // Main interface
│ ├── ResultsScreen.jsx // AI recommendations
│ └── ProfileScreen.jsx // Account management
├── services/
│ ├── supabase.js // Database config
│ ├── openai.js // AI integration
│ └── stripe.js // Payments
├── hooks/
│ ├── useAuth.js // Authentication state
│ ├── useCamera.js // Camera permissions
│ └── useSubscription.js // Premium status
└── App.jsx // Main navigation
// Automatic Expo configuration
{
"expo": {
"name": "SOMMIA",
"slug": "sommia",
"version": "1.0.0",
"platforms": ["ios", "android"],
"icon": "./assets/icon.png",
"splash": {
"image": "./assets/splash.png",
"backgroundColor": "#8B1538"
},
"plugins": [
"expo-camera",
"expo-image-picker",
["expo-stripe-checkout", {
"merchantId": "merchant.com.sommia"
}]
]
}
}
// Supabase authentication hook
import { useEffect, useState } from 'react';
import { supabase } from '../services/supabase';
export function useAuth() {
const [session, setSession] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session);
setLoading(false);
});
const { data: { subscription } } = supabase.auth.onAuthStateChange(
(_event, session) => {
setSession(session);
}
);
return () => subscription.unsubscribe();
}, []);
return { session, loading };
}
The "Wow" Moments with Bolt
- Sophisticated AI Integration The most impressive part was watching Bolt generate the AI recommendation system. My prompt: "Add an AI system that analyzes dish photos, determines optimal wine pairings based on budget and user preferences"
- Instant Native UI/UX Asking for "modern and premium design with smooth animations" produced an interface that looked like it came from a professional design studio.
- Complex State Management Simplified Subscription logic with Stripe, cache management, authentication... all generated in a few prompts.
// AI Service generated by Bolt.new
import { openai } from './openai';
import { supabase } from './supabase';
import AsyncStorage from '@react-native-async-storage/async-storage';
export class WineRecommendationService {
static async analyzeImage(imageUri, userPreferences, budget) {
try {
// Cache check
const cacheKey = `analysis_${imageUri}_${budget}`;
const cached = await AsyncStorage.getItem(cacheKey);
if (cached) return JSON.parse(cached);
// Image analysis
const base64Image = await this.convertToBase64(imageUri);
const prompt = `
Analyze this dish image and recommend 3 perfect French wines.
Budget: €${budget} maximum per bottle
Preferences: ${JSON.stringify(userPreferences)}
Respond in JSON with:
{
"dish_detected": "dish name",
"confidence": 95,
"recommendations": [
{
"wine_name": "Sancerre Les Monts Damnés",
"producer": "Henri Bourgeois",
"region": "Loire Valley",
"vintage": 2022,
"price_estimate": 18,
"match_score": 95,
"reasoning": "This Sancerre brings perfect minerality...",
"color": "white",
"characteristics": ["mineral", "crisp", "elegant"]
}
]
}
`;
const response = await openai.chat.completions.create({
model: "gpt-4-vision-preview",
messages: [
{
role: "user",
content: [
{ type: "text", text: prompt },
{ type: "image_url", image_url: { url: base64Image } }
]
}
],
max_tokens: 1500,
temperature: 0.7
});
const analysis = JSON.parse(response.choices[0].message.content);
// Cache result
await AsyncStorage.setItem(cacheKey, JSON.stringify(analysis));
// Store in Supabase
await this.storeRecommendation(analysis, userPreferences);
return analysis;
} catch (error) {
console.error('Wine analysis failed:', error);
return this.getFallbackRecommendations(budget);
}
}
static async getFallbackRecommendations(budget) {
const { data: wines } = await supabase
.from('wines')
.select('*')
.lte('price_estimate', budget)
.order('rating', { ascending: false })
.limit(3);
return {
dish_detected: "Detected dish",
confidence: 75,
recommendations: wines.map(wine => ({
...wine,
match_score: 85,
reasoning: `Excellent choice within your €${budget} budget`
}))
};
}
static async convertToBase64(imageUri) {
const response = await fetch(imageUri);
const blob = await response.blob();
return new Promise((resolve) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
}
static async storeRecommendation(analysis, userPreferences) {
const { data: { user } } = await supabase.auth.getUser();
await supabase.from('recommendations').insert({
user_id: user?.id,
dish_description: analysis.dish_detected,
ai_analysis: analysis,
user_preferences: userPreferences,
created_at: new Date().toISOString()
});
}
}
From Bolt.new to App Store
Export and Deployment
The workflow was surprisingly simple:
Code download from Bolt.new
EAS CLI setup: npm install -g @expo/eas-cli
Configuration: eas build:configure
iOS build: eas build --platform ios
Submission: eas submit --platform ios
Technical Challenges Solved by Bolt
Problem: Cross-platform camera permissions management
Bolt Solution: Automatic code with elegant fallbacks
Problem: Complex Stripe integration
Bolt Solution: Ready-to-use React hooks
Problem: Performance with 10k+ wine database
Bolt Solution: Optimized caching and pagination systems
Concrete Results
Timeline Met
Day 1: Complete architecture generated
Day 2: AI + Supabase + Stripe integrations
Day 3: UI polish + testing
Day 4: Build + App Store submission
Technical Metrics
Bundle size: 15MB (automatically optimized)
Time to Interactive: <2 seconds
Crash rate: 0% (Expo Go testing)
Performance: Consistent 60 FPS
Business Impact
Concept validation: Functional app proves viability
Investor pitch: Live demo vs mockups
User feedback: Real user insights from week 1
What I Learned
Bolt.new's Superpowers
Speed to MVP: 48h vs 2 months traditional
Best practices: Professional code out-of-the-box
Rapid iteration: Real-time changes
Modern stack: Latest versions automatically
Clean export: Maintainable and extensible code
Honest Limitations
AI complexity: Sophisticated prompts required
Deep customization: Sometimes faster to code directly
Advanced debugging: Stack traces less obvious
Dependencies: Sometimes conservative choices
Tips to Maximize Bolt
Start simple then add complexity
Specific prompts with examples
Iterate in small steps
Download regularly to save code
Test on device with Expo Go
My Advice to Builders
If you have an app idea that excites you:
Write a detailed prompt with your vision
Let Bolt.new generate the architecture
Iterate quickly with real users
Export and deploy as soon as possible
Top comments (0)