Building Custom AI App Solutions: A Technical Architecture Guide
How to Build a Custom React Frontend for Gemini Using the Base44 Framework
For enterprise technical directors evaluating how to ship custom AI applications quickly without sacrificing architectural control, this guide breaks down the full stack: from React frontend patterns to Gemini API integration, structured outputs, authentication, and deployment — all on the Base44 platform.
Why Custom AI Apps Over Off-the-Shelf Tools
Most enterprise AI initiatives stall at the prototype stage. Teams build a promising chatbot demo in a notebook, then discover that productionising it requires authentication, state management, audit trails, role-based access, structured data persistence, and a polished UI that non-technical staff can actually use.
Custom AI apps solve this by treating the LLM as one component within a complete product architecture — not the product itself. The AI is embedded inside a real application with user accounts, dashboards, permissions, data validation, and business logic that your organisation controls end to end.
The Base44 Advantage
Base44 provides a backend-as-a-service layer that handles auth, database, serverless functions, integrations, and hosting — meaning your engineering team focuses on the application layer, not infrastructure plumbing. Combined with a React + Tailwind frontend and Google's Gemini API, you can ship production-grade AI applications in days rather than quarters.
Architecture Overview
A typical custom AI app on Base44 consists of four layers:
- React Frontend — Built with Vite, React, and Tailwind CSS. Handles UI state, user interactions, and renders AI responses.
- Base44 Backend — Entities (database schemas), serverless functions (Deno Deploy handlers), and built-in integrations (LLM invocation, file uploads, email).
- Gemini API — Called through Base44's integration layer for text generation, structured output, and multimodal reasoning.
- Auth Layer — Base44's built-in authentication with email/password, OAuth providers, and role-based access control.
Step 1: Setting Up the Base44 Project
When you create a Base44 app, you get a full Vite + React + Tailwind project with:
- Pre-configured auth pages (login, register, OTP, password reset)
- An entity system (JSON schemas that define your database)
- A serverless function runtime (Deno Deploy)
- Built-in SDK client (
@/api/base44Client) - shadcn/ui component library
The SDK client is pre-initialised and available at @/api/base44Client:
import { base44 } from '@/api/base44Client';
// Check if user is authenticated
const isAuthed = await base44.auth.isAuthenticated();
// Get current user
const user = await base44.auth.me();
Step 2: Building the React Frontend
For an AI app, the frontend needs to handle:
- Prompt input — A textarea or form where users describe what they need
- Response rendering — Markdown rendering for AI-generated content
- Loading states — Visual feedback while the LLM processes
- Conversation history — Previous prompts and responses
Here's a pattern for a React component that invokes Gemini through the Base44 SDK:
import { useState } from 'react';
import { base44 } from '@/api/base44Client';
import ReactMarkdown from 'react-markdown';
export default function AIAssistant() {
const [prompt, setPrompt] = useState('');
const [response, setResponse] = useState('');
const [loading, setLoading] = useState(false);
const handleSubmit = async () => {
if (!prompt.trim()) return;
setLoading(true);
setResponse('');
try {
const result = await base44.integrations.Core.InvokeLLM({
prompt: prompt,
add_context_from_internet: true,
response_json_schema: null
});
setResponse(result);
} catch (error) {
setResponse('Sorry, something went wrong. Please try again.');
} finally {
setLoading(false);
}
};
return (
<div className="max-w-3xl mx-auto p-6">
<textarea
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
placeholder="Ask anything..."
className="w-full p-4 rounded-lg border bg-black/40 text-white"
/>
<button onClick={handleSubmit} disabled={loading}>
{loading ? 'Processing...' : 'Submit'}
</button>
{response && (
<ReactMarkdown className="prose prose-invert mt-6">
{response}
</ReactMarkdown>
)}
</div>
);
}
Step 3: Integrating the Gemini API
Base44's InvokeLLM integration is the primary interface to Gemini. Key parameters:
prompt— The user's instruction or questionadd_context_from_internet— Set totrueto give Gemini web search capabilities (uses Gemini 3 Flash or Gemini 3.1 Pro)response_json_schema— Define a JSON schema to force structured outputfile_urls— Attach files (images, documents) for multimodal reasoningmodel— Specify a model (defaults to automatic; usegemini_3_flashfor speed,gemini_3_1_profor complex reasoning)
Structured Outputs
One of the most powerful patterns for enterprise AI apps is forcing the LLM to return structured JSON rather than freeform text. This enables reliable downstream processing:
const result = await base44.integrations.Core.InvokeLLM({
prompt: `Analyse this customer feedback and extract: sentiment, key themes, urgency level, and recommended action.`,
response_json_schema: {
type: "object",
properties: {
sentiment: { type: "string", enum: ["positive", "neutral", "negative"] },
themes: { type: "array", items: { type: "string" } },
urgency: { type: "string", enum: ["low", "medium", "high"] },
recommended_action: { type: "string" }
},
required: ["sentiment", "themes", "urgency", "recommended_action"]
}
});
// result is already a parsed object — no JSON.parse needed
console.log(result.sentiment); // "negative"
console.log(result.themes); // ["billing", "response time"]
Step 4: Building a Backend Function for Complex AI Workflows
For multi-step AI workflows (e.g., retrieve data, call Gemini, store result, send notification), use a Base44 backend function. These run on Deno Deploy:
import { createClientFromRequest } from 'npm:@base44/sdk@0.8.31';
Deno.serve(async (req) => {
try {
const base44 = createClientFromRequest(req);
const user = await base44.auth.me();
if (!user) return Response.json({ error: 'Unauthorized' }, { status: 401 });
const { query } = await req.json();
// Call Gemini with structured output
const analysis = await base44.asServiceRole.integrations.Core.InvokeLLM({
prompt: `Analyse this business query and provide recommendations: ${query}`,
response_json_schema: {
type: "object",
properties: {
summary: { type: "string" },
recommendations: { type: "array", items: { type: "string" } },
confidence: { type: "number" }
},
required: ["summary", "recommendations", "confidence"]
}
});
// Store the analysis in the database
const record = await base44.asServiceRole.entities.AIAnalysis.create({
user_id: user.id,
query: query,
result: JSON.stringify(analysis),
created_at: new Date().toISOString()
});
return Response.json({ analysis, record });
} catch (error) {
return Response.json({ error: error.message }, { status: 500 });
}
});
Step 5: Authentication and Security
Base44 provides a complete auth system out of the box:
- Email/password with OTP verification
- OAuth providers (Google, Microsoft, Apple)
- Role-based access control at the entity level (RLS)
- Protected routes via
ProtectedRoutecomponent
Entity-level security (RLS) ensures data isolation:
{
"rls": {
"create": {},
"read": { "user_condition": { "role": "admin" } },
"update": { "user_condition": { "role": "admin" } },
"delete": { "user_condition": { "role": "admin" } }
}
}
This means only admins can read/update/delete records, while any visitor can create new submissions — perfect for lead capture forms.
Step 6: Real-time Updates
Base44 supports real-time entity subscriptions, which is essential for AI apps that need to show live updates (e.g., as an analysis completes):
useEffect(() => {
const unsubscribe = base44.entities.AIAnalysis.subscribe((event) => {
if (event.type === 'create') {
// New analysis available — update the UI
setAnalyses(prev => [event.data, ...prev]);
}
});
return unsubscribe;
}, []);
Step 7: Deployment and Scaling
Base44 handles deployment automatically — every save triggers a build and deploy. The platform manages:
- CDN distribution for static assets
- Serverless function scaling on Deno Deploy
- Database scaling (PostgreSQL-backed)
- SSL/TLS certificates
- Custom domain configuration
For enterprise deployments, consider:
- Environment variables for API keys and secrets (set in dashboard)
- Admin-only functions for sensitive operations (verify
user.role === 'admin') - Audit logging via entity records for compliance
- Rate limiting at the function level for API protection
Monitoring and Analytics
Base44 includes built-in analytics tracking:
base44.analytics.track({
eventName: 'ai_query_submitted',
properties: { query_type: 'analysis', tokens_used: 500 }
});
For production AI apps, track:
- Query volume and patterns
- Response times and token usage
- User satisfaction signals (thumbs up/down)
- Error rates by model and prompt type
- Cost per query (integration credits consumed)
Conclusion
Building custom AI applications doesn't have to mean months of infrastructure work. By combining React for the frontend, Base44 for the backend, and Gemini for intelligence, enterprise teams can ship production-grade AI tools that integrate with existing systems, respect data governance requirements, and provide real business value.
The architecture is simple but extensible: start with a single AI-powered feature, validate with users, then expand to multi-step workflows, scheduled automations, and full agent systems — all on the same platform, without re-architecting.
HEX TOYS specialises in building custom AI applications for enterprise teams. Book a consultation to discuss your specific requirements.