Build an AI Ghibli Filter App with the AI Pass SDK
Build an AI Ghibli Filter App with the AI Pass SDK
Studio Ghibli's art style is one of the most beloved visual aesthetics on the planet. Building an app that transforms photos into Ghibli-inspired artwork is a crowd-pleaser — and with the AI Pass SDK, you can have it running in an afternoon.
This tutorial walks through building a complete Ghibli filter web app: photo upload, AI transformation, result display, and deployment options.
Prerequisites
- Basic HTML/JavaScript knowledge
- An AI Pass account — sign up at aipass.one ($1 free credit included)
- A Client ID from the Developer Dashboard
Step 1: Get Your Client ID
- Sign up or log in at aipass.one
- Open the Developer Dashboard
- Navigate to OAuth2 Clients tab
- Click Create New Client — give it a name like "Ghibli Filter App"
- Copy your
client_XXXX...Client ID
This is your YOUR_CLIENT_ID in the code below.
Step 2: The App Structure
Create an index.html file with this complete app:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Ghibli Filter</title>
<script src="https://aipass.one/aipass-sdk.js"></script>
<style>
body {
font-family: 'Segoe UI', sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 2rem;
background: #f0f4e8;
color: #333;
}
h1 { color: #4a7c59; text-align: center; }
.upload-area {
border: 2px dashed #4a7c59;
border-radius: 12px;
padding: 2rem;
text-align: center;
cursor: pointer;
transition: background 0.2s;
}
.upload-area:hover { background: #e8f0e0; }
.preview-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
margin-top: 1.5rem;
}
img { width: 100%; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.1); }
button {
background: #4a7c59;
color: white;
border: none;
padding: 0.75rem 2rem;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
width: 100%;
margin-top: 1rem;
}
button:disabled { opacity: 0.6; cursor: not-allowed; }
#status { text-align: center; margin-top: 0.75rem; color: #4a7c59; }
</style>
</head>
<body>
<h1>🌿 AI Ghibli Filter</h1>
<p style="text-align:center">Transform your photos into Studio Ghibli art</p>
<div class="upload-area" onclick="document.getElementById('fileInput').click()">
<p>📁 Click to upload a photo (or drag & drop)</p>
<input type="file" id="fileInput" accept="image/*" style="display:none">
</div>
<div class="preview-grid" id="previewGrid" style="display:none">
<div>
<p><strong>Original</strong></p>
<img id="originalPreview">
</div>
<div>
<p><strong>Ghibli Style</strong></p>
<img id="ghibliResult" src="" style="display:none">
<div id="placeholder" style="background:#e8f0e0;height:200px;border-radius:8px;display:flex;align-items:center;justify-content:center;color:#4a7c59">Result will appear here</div>
</div>
</div>
<button id="transformBtn" style="display:none" onclick="transformToGhibli()">🎨 Transform to Ghibli Style</button>
<p id="status"></p>
<script>
AiPass.initialize({
clientId: 'YOUR_CLIENT_ID',
requireLogin: true,
darkMode: false
});
let selectedFile = null;
document.getElementById('fileInput').addEventListener('change', (e) => {
selectedFile = e.target.files[0];
if (!selectedFile) return;
const reader = new FileReader();
reader.onload = (ev) => {
document.getElementById('originalPreview').src = ev.target.result;
document.getElementById('previewGrid').style.display = 'grid';
document.getElementById('transformBtn').style.display = 'block';
document.getElementById('ghibliResult').style.display = 'none';
document.getElementById('placeholder').style.display = 'flex';
};
reader.readAsDataURL(selectedFile);
});
async function transformToGhibli() {
if (!selectedFile) return;
const btn = document.getElementById('transformBtn');
const status = document.getElementById('status');
btn.disabled = true;
status.textContent = '✨ Applying Ghibli magic... (15-30 seconds)';
try {
// Convert file to base64
const base64 = await fileToBase64(selectedFile);
const mimeType = selectedFile.type || 'image/jpeg';
// Call AI Pass image editing via chat completions (Gemini image model)
const result = await AiPass.generateCompletion({
model: 'gemini/gemini-3-pro-image-preview',
temperature: 1,
max_tokens: 16000,
messages: [{
role: 'user',
content: [
{
type: 'text',
text: 'Transform this photo into Studio Ghibli anime art style. Make it look like a scene from a Hayao Miyazaki film — warm colors, hand-painted feel, soft natural lighting, lush backgrounds, and the characteristic Ghibli aesthetic. Preserve the main subject and composition but fully reimagine it in Ghibli style. Return the transformed image.'
},
{
type: 'image_url',
image_url: { url: `data:${mimeType};base64,${base64}` }
}
]
}]
});
// The result content contains the image URL or base64
const content = result.choices[0].message.content;
// Extract image URL from response
const imgMatch = content.match(/!\[.*?\]\((https?:\/\/[^)]+)\)/) ||
content.match(/(https?:\/\/[^\s]+\.(?:png|jpg|jpeg|webp))/i);
if (imgMatch) {
document.getElementById('ghibliResult').src = imgMatch[1];
document.getElementById('ghibliResult').style.display = 'block';
document.getElementById('placeholder').style.display = 'none';
status.textContent = '🌿 Ghibli transformation complete!';
} else {
status.textContent = '⚠️ Transformation done — check console for output';
console.log('AI Response:', content);
}
} catch (err) {
status.textContent = '❌ Error: ' + err.message;
console.error(err);
}
btn.disabled = false;
}
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => resolve(e.target.result.split(',')[1]);
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
</script>
</body>
</html>
Step 3: Configure Your Client ID
Replace YOUR_CLIENT_ID with your actual Client ID from the Developer Dashboard. It looks like client_XXXX... — never hardcode real API keys.
The requireLogin: true setting means users will see an AI Pass login screen before they can use your app. This handles authentication and billing automatically.
Step 4: Deploy Your App
Option A — Self-Host (full control)
Deploy to any static hosting:
# Netlify drop
npx netlify-cli deploy --dir . --prod
# Or Vercel
npx vercel --prod
# Or simple Python server for testing
python3 -m http.server 3000
Option B — Publish on AI Pass Catalog
- Open the Developer Dashboard
- Go to Apps → Publish New App
- Set the app URL and details
- Submit for review
Published apps on the AI Pass catalog get free organic traffic. You also earn 50% commission on every API call your users make. If your Ghibli filter goes viral, that adds up fast.
Step 5: Embed on Any Website
Any published AI Pass app can be embedded via iframe. Click the </> button at the bottom-right of any app to get the embed code. Perfect for adding to a portfolio site or blog.
Going Further
Some ideas to extend the app:
- Multiple styles — add a style selector (Ghibli, Pixel Art, Watercolor)
- Download button — let users save the generated image
- Gallery — store recent transformations with localStorage
- Social sharing — pre-fill a tweet or Instagram caption with the image
Resources
You now have a fully working AI Ghibli filter web app. Deploy it, share it, and start earning 50% on every transformation your users create.