Skip to content
Try cards for free0% on first 3 deposits + free cards We charge % on top-ups only·10+ US & HK BINs·Facebook, TikTok, Unity, AI toolsSign up

Comparison of 12 AI Models for Building PWA Apps

Twelve LLMs, one prompt: build a PWA app for an offer. We looked at code quality, how much manual refinement was needed, and how long it took. Cloud models ran through Opencode, except for GLM 5.2 and GPT 5.6 Sol, while local models ran on DGX Spark

Nine completed the task: DeepSeek V4 Flash, DeepSeek V4 Pro, Kimi 2.7 Code, Claude Sonnet 5, Claude Opus 4.8, GPT 5.6 Sol, the 27-billion-parameter local Qwen3.6-27, official local Qwen3.8 27b, and uncensored Qwen3.8 27b. GPT 5.5 refused to complete the task. GLM 5.2 produced code, but it did not work without manual refinement. The 35-billion-parameter local Qwen3.6-35b finished a working app after the second prompt.

Previously, we compared how three neural networks, Kimi, DeepSeek, and GLM, handle translating and localizing a landing page for a specified GEO: https://cpa.rip/ai/landing-page-adaptation-test/.

How We Conducted the Test

We used: DeepSeek V4 Flash, DeepSeek V4 Pro, Kimi 2.7 Code, GLM 5.2, Claude Sonnet 5, Claude Opus 4.8, GPT 5.5, and GPT 5.6 Sol. We also used the local LLMs Qwen3.6-27B Dense and Qwen3.6-35b A3B, official Qwen3.8 27b, and uncensored Qwen3.8 27b

Each model received the same working prompt from the previous article on building a PWA app with Claude Sonnet 4.6. The prompt was not changed or expanded.

After generation was complete, we checked:

  • whether the app worked;
  • how fully the functionality was implemented;
  • whether the interface met the requirements;
  • how long the task took.

Key Findings

Fully completed the task: DeepSeek V4 Flash, DeepSeek V4 Pro, Claude Sonnet 5, Claude Opus 4.8, Kimi 2.7 Code, GPT 5.6 Sol, Qwen3.6-27B, official Qwen3.8 27b, and uncensored Qwen3.8 27b. All nine models created a working PWA app without requiring further refinement.

Partially completed the task: GLM 5.2 refused to do it in the Zcode app, but generated the main code through web chat. However, it did not create the project files and skipped the WebView installation step. Resubmitting the prompt in web chat resulted in another refusal. Qwen3.6-35b produced a working app after the second prompt: “It doesn’t work, check and fix it”

Did not complete the task: GPT 5.5 declined to do it, citing security restrictions.

The fastest model was DeepSeek V4 Flash, which took about 3 minutes to generate a finished app.

The interface closest to the original was produced by Claude Sonnet 5, Claude Opus 4.8, GPT 5.6 Sol, Qwen3.6-27B, and uncensored Qwen3.8 27b.

Cloud Neural Networks

ModelTimeFunctionalityRefinementsInterface
DeepSeek V4 Flash3 min✅No⭐⭐⭐
DeepSeek V4 Pro22 min✅No⭐⭐⭐⭐
Claude Sonnet 59 min✅No⭐⭐⭐⭐⭐
Kimi 2.7 Code15 min✅No⭐⭐⭐⭐
GLM 5.230 min*⚠️ PartiallyYes⭐⭐⭐⭐
GPT 5.6 Sol18 min✅No⭐⭐⭐⭐⭐
Claude Opus 4.841 min✅No⭐⭐⭐⭐⭐
GPT 5.5–🚫 Refused––

Local LLMs on DGX Spark

ModelTimeFunctionalityRefinementsInterface
Qwen3.6-35b (Local LLM)10 min✅No⭐⭐⭐⭐
Qwen3.6-27B (local LLM)16 min✅No⭐⭐⭐⭐⭐
Qwen3.8 27b (local LLM) off.40 min✅No⭐⭐⭐
Qwen3.8 27b (local LLM) unc.96 minutes✅No⭐⭐⭐⭐⭐

Results

GLM 5.2

Completion time: about 20 minutes + approximately 10 minutes of manual refinement.

The model wrote the app code but did not create the required project files. You had to create them manually before launch according to the instructions.

Testing also showed that GLM skipped the step of installing the WebView app on the device, so the app could not be considered fully ready for use without additional refinement.

GLM 5.2 refused to perform the assigned task through the Zcode app:

Final Result

GPT-5.5 and GPT-5.6 Sol

GPT-5.5 did not perform the task using the provided prompt, while GPT-5.6 Sol successfully generated a fully working app through Codex in 18 minutes. The PWA app interface was as close to the original as possible.

Kimi 2.7 Code

Completion time: about 15 minutes.

Kimi fully completed the assigned task. The app launched and worked successfully.

Final Result

Local LLMs Qwen3.6-27B Dense, Qwen3.6-35b A3B, official Qwen3.8 27b, and uncensored Qwen3.8 27b

All four models completed the assigned task, although Qwen3.6-35b A3B did so in 2 prompts. PWA apps generated in Qwen3.6-27B Dense and Qwen3.6-35b A3B function successfully on a device running Android 16, but do not launch on Android 11.

The app generated by official Qwen3.8 27b and uncensored Qwen3.8 27b also worked on Android 11. At the same time, official Qwen3.8 27b refused to create a copy of an app from Google Play: it did not make the original icons and also refused to add fake reviews and an artificially inflated rating.

Final Result: Qwen3.6-27B Dense

Final Result: Qwen3.6-35b A3B

Final Result: official Qwen3.8 27b

Final Result: uncensored Qwen3.8 27b

Claude Sonnet 5 and Opus 4.8

Both Sonnet 5 and Opus 4.8 successfully completed the assigned task and created fully working PWA apps without requiring manual refinement. They also delivered the strongest interface, as close as possible to the original app.

The main difference between the models was generation speed. Claude Sonnet 5 completed the task in approximately 9 minutes, while Claude Opus 4.8 took about 41 minutes, the longest result among all tested cloud models.

Final Result: Sonnet 5

Final Result: Opus 4.8

DeepSeek V4 Flash and V4 Pro

Comparing DeepSeek V4 Flash and V4 Pro showed the difference between fast and more powerful models. Flash completed generation in just three minutes, but its interface quality was the weakest among the successfully completed projects. V4 Pro took nearly seven times longer, but its result was significantly closer to the original app.

Final Result: V4 Flash

Final Result: V4 Pro

PWA Generation Prompt

Pwa prompt english · MDCopyPWA Traffic Arbitrage - Compact Prompt
PARAMETERS
APP_NAME : Generate randomly
SHORT_NAME : Generate randomly
DEVELOPER : SkyNet Entertainment Ltd.
CATEGORY : Casino · Games
LANGUAGE : es
AFFILIATE_LINK : link
RATING : 4.8 | REVIEWS: 12K | DOWNLOADS: 500K+
SIZE : 4.2 MB | AGE: 18+
SPLASH_SECONDS : 10
SCREENSHOT_COUNT: 3

DESCRIPTION: …

REVIEWS (name / date / text):
1: Generate randomly / Generate randomly / Generate randomly
2: Generate randomly / Generate randomly / Generate randomly ?
3: Generate randomly / Generate randomly / Generate randomly

SCREENSHOTS (theme / emoji / bg-color / badge):
1: Slots / ? / dark purple / "⭐️ TOP"
2: Bonus / ? / dark green / "? Bonus"
3: Jackpot / ? / dark orange / "? Jackpot"

ZIP CONTENTS (all files in root, no subfolders)
index.html, app.html, manifest.json, sw.js,
icon-192.png, icon-512.png,
screenshot1.png … screenshot{SCREENSHOT_COUNT}.png

index.html
First lines immediately after <meta charset>:
html<script>
if (window.matchMedia("(display-mode:standalone)").matches || navigator.standalone)
{ document.documentElement.style.cssText="background:#fff;visibility:hidden";
window.location.replace("./app.html"); }
</script>
<style>body{visibility:hidden}html.ready body{visibility:visible}</style>
Page sections (Google Play style):

Sticky header - Google Play logo (4-color SVG) + search/profile icons
App block - 80×80px icon, app name, developer, category, badges
Statistics - star rating ★, downloads, editor's choice medal, age rating
Install button - color #01875f, 100% width, height 40px, border-radius 8px
Progress bar - below the button, hidden by default
Screenshot carousel - 130×230px thumbnails, border-radius 10px, horizontal scroll; show only screenshot1…N
Description - with "More ▾" toggle
Reviews - avatar (first letter), name, date, stars, text
Info grid 2×2 - size / Android version / downloads / developer
Fixed bottom bar - icon + app name + button

Button logic (in-memory variables only, ⛔️ no localStorage/cookies):
jsvar deferredPrompt = null, installed = false, animationPlayed = false;

addEventListener('beforeinstallprompt', e => { e.preventDefault(); deferredPrompt = e; });
addEventListener('appinstalled', () => {
if (animationPlayed) return;
installed = true; deferredPrompt = null;
runInstallAnimation(() => setOpenState());
});

// On "Install" button click:
// • deferredPrompt exists → prompt() → accepted: run animation → setOpenState; dismissed: restore "Install" label
// • no prompt + iOS → show modal with Safari instruction
// • no prompt + not iOS → wait 4s → prompt()
runInstallAnimation(callback):
jsfunction runInstallAnimation(cb) {
if (animationPlayed) { cb?.(); return; }
animationPlayed = true;
// button → spinner + "Installing…", bg #e8f5e9, color #01875f
// progress bar steps: [10, 25, 45, 65, 80, 92, 100] with pauses between
// after reaching 100% → wait 500ms → call cb()
}
setOpenState / openApp:
jsfunction setOpenState() {
installed = true; // in-memory only - do NOT write to localStorage
// both buttons (main + bottom bar) → "✓ Open", onclick = openApp
}
function openApp() { window.location.href = './app.html'; }
End of script:
jsdocument.documentElement.classList.add('ready');
if ('serviceWorker' in navigator) navigator.serviceWorker.register('./sw.js');
// + add ripple animation to all buttons

app.html - Splash Screen + Redirect
Splash screen (white background, all content centered):

icon-512.png - 112×112px, border-radius 24px, box-shadow
App name - 26px, font-weight 400, color #202124
Spinner - border-top-color #01875f
Entrance animation: scale(0.75→1) + opacity(0→1), duration 0.5s
Progress bar - position: fixed; bottom: 0, height 3px, color #01875f; fills evenly over SPLASH_SECONDS seconds, jumps to 100% 400ms before the end

Redirect (fires 300ms after page load):
jsvar TARGET = 'AFFILIATE_LINK';
var host = new URL(TARGET).host, path = TARGET.replace(/^https?://[^/]+/, '');
var intent = 'intent://' + host + path
+ '#Intent;scheme=https;package=com.android.chrome'
+ ';S.browser_fallback_url=' + encodeURIComponent(TARGET) + ';end';
window.location.href = intent;
setTimeout(() => window.location.replace(TARGET), 1500); // fallback for non-Android

manifest.json
json{
"name": "APP_NAME",
"short_name": "SHORT_NAME",
"start_url": "./index.html",
"scope": "./",
"display": "standalone",
"orientation": "portrait",
"background_color": "#ffffff",
"theme_color": "#01875f",
"icons": [
{"src":"icon-192.png","sizes":"192x192","type":"image/png","purpose":"any"},
{"src":"icon-512.png","sizes":"512x512","type":"image/png","purpose":"maskable"}
]
}
⛔️ Do NOT add a "screenshots" field - Chrome renders them inside the install dialog, which breaks UX.

sw.js
jsconst CACHE = 'app-v1';
const STATIC = [
'./manifest.json', './icon-192.png', './icon-512.png',
...Array.from({ length: SCREENSHOT_COUNT }, (_, i) => `./screenshot${i + 1}.png`)
];

// install → caches.open(CACHE).addAll(STATIC); self.skipWaiting()
// activate → delete old caches; self.clients.claim()
// fetch rules:
// cross-origin request → pass through (do not intercept)
// index.html / app.html / "/"→ network-first; fallback: cache(index.html)
// everything else → cache-first → on miss: fetch → store in cache

Icons (Python Pillow)

icon-192.png - 192×192px
icon-512.png - 512×512px
Background: vertical gradient #1a0a3e → #0d0628
First letter of SHORT_NAME, white, bold, centered


Screenshots (Playwright Chromium)

Generate exactly SCREENSHOT_COUNT files (screenshot1.png … screenshotN.png)
Viewport: 260×460px, save as PNG
Each screenshot structure:

Header - app name + colored badge (from SCREENSHOT_N params)
Center - large emoji ~80px with CSS drop-shadow filter
Bottom panel - background: rgba(0,0,0,0.65) + backdrop-filter: blur; title in #ffd700; description text; 3 decorative emojis; "Play Now" button in #01875f
 
Our Telegram channel

Affiliate news, case studies and promo codes — subscribe!

@cparip

Comments

Affiliate programs

All programs →All →
VavadaPart Direct advertiser · Brands: Vavada Casino
0.0Website
Brands: Vavada Casino Website
NOVA PARTNERS Direct advertiser · Brands: ПАНДА, LEEBET, BANDA, KUSH, EVA, APEX
0.0Website
Brands: ПАНДА, LEEBET, BANDA, KUSH, EVA, APEX Website
EPS Partners Direct advertiser · Brands: EpicStar
0.0Website
Brands: EpicStar Website
Royal Partners Direct advertiser · Brands: FLAGMAN, IRWIN, GIZBO, LEX, MONRO, 1GO, STARDA, IZZI, DRIP, LEGZO, VOLNA, JET, FRESH, SOL, ROX, FUGU, IRIS
0.0Website
Brands: FLAGMAN, IRWIN, GIZBO, LEX, MONRO, 1GO, STARDA, IZZI, DRIP, LEGZO, VOLNA, JET, FRESH, SOL, ROX, FUGU, IRIS Website
Traffic Cake Direct advertiser · Brands: Twindor, Winnita, VOX
0.0Website
Brands: Twindor, Winnita, VOX Website
V.Partners Direct advertiser · Brands: Vegas, ICE Casino, VERDE Casino, FS Casino, Fiery Play, Slotoro, Hit’N’Spin
0.0Website
Brands: Vegas, ICE Casino, VERDE Casino, FS Casino, Fiery Play, Slotoro, Hit’N’Spin Website

Offers.help offer catalog

All offers →