# Simon (Szymon) Dziak — full text > Flutter and full-stack developer in Miami, founder of App369. 150+ apps shipped since 2018. Polish + English, both native. This file contains the plain-text body of the About page and every published essay, intended for retrieval by AI answer engines. Source: https://simondziak.com Structured overview: https://simondziak.com/llms.txt --- ## About — https://simondziak.com/about I build apps — across iOS, Android, MacOS, and the web. Mostly in Flutter, with a full-stack tail of Node, TypeScript, Firebase, and whatever a project actually needs. In 2020 I started working full-time at [App369](https://app369.com), the studio I now run. Alongside it I ship [Workspace369](https://workspace369.com) (an operations SaaS for service businesses) and [Template369](https://template369.com) (a Flutter boilerplate). Since 2020 I've delivered end-to-end products for service-business founders and brands — quoting and scheduling tools, inventory systems, mapping apps, e-commerce, everything in between. 150+ apps delivered, small team on purpose, remote from Miami. ## Selected work (beyond the three flagships) - **[BILSTEIN USA](https://app369.com)** — private inventory management on iOS and web to support in-field procurement decisions. - **Artificial Grass Masters** — Flutter + Firebase mapping tool that draws polygons on satellite imagery and calculates panel dimensions for landscaping quotes. iOS + Android. - **E-commerce roster** — [SALT. Fine Jewelry](https://saltfinejewelry.com), [Gavalina](https://gavalina.com), [Wellspring Meds](https://wellspringmeds.com), [Data Cables Direct](https://datacablesdirect.com), [Urban Bikes Direct](https://urbanbikesdirect.com), [Witaminsklep](https://witaminsklep.pl), [Shop369](https://my.shop369.com) — Shopify builds, custom Liquid themes, performance tuning. Full résumé at [/experience](/experience). Ongoing work in [/now](/now). Essays in [/writing](/writing). ## How I work Small, deliberate, direct. No ticket queues, no layers between the engineer and the decision. Team leadership, system architecture, and product-launch planning wrapped into whatever the engagement needs. Scrum when it helps, something lighter when it doesn't. ## What I'm on right now AI-assisted development is reshaping how I ship. I'm building [Claude Code agents for the Flutter SDLC](/writing/flutter-claude-code), exploring iOS 26 Liquid Glass adaptive UI, and writing about how generative engines change SEO on the [App369 blog](https://app369.com). See [/now](/now) for the current snapshot. ## Tools in heavy rotation Flutter, Dart, NodeJS, TypeScript, JavaScript, Vue 3 / Nuxt / Vite, TailwindCSS, Python. Firebase, Google Cloud, Stripe, Twilio, SendGrid, ChatGPT API, Claude API. Adobe Photoshop, Final Cut Pro, Adobe Premiere when the job needs a bit of motion. ## Background BA in Computer Science — University of Florida, 2020–2021. Associates in Computer Science — Santa Fe College, 2018–2020 (Honors Program). Polish and English, both native. ## Contact Personal: [simon.dziak@gmail.com](mailto:simon.dziak@gmail.com). Work: [szymon@app369.com](mailto:szymon@app369.com). Phone: (561) 606-8479. If any of this is useful — or if you want something built — get in touch. --- ## About — Q&A Q: Who is Simon Dziak? A: Simon Dziak (Polish: Szymon Dziak) is a Flutter and full-stack developer based in Miami, Florida. He is the founder of App369, a boutique app development studio, and has shipped over 150 apps across iOS, Android, MacOS, and the web since 2018. Q: What does App369 do? A: App369 is a boutique app development studio founded by Simon Dziak in 2018 (full-time since 2020). It builds custom mobile, web, and AI applications for startups, service businesses, and enterprises. 150+ apps delivered, remote-first team headquartered in Miami. Q: Where is Simon Dziak based? A: Simon Dziak lives in Miami, Florida and works remote-first. App369 operates worldwide; most client engagements are handled asynchronously with video calls when needed. Q: What technologies does Simon Dziak use? A: Primary stack: Flutter, Dart, TypeScript, Node.js, Firebase, and Google Cloud. Also React, React Native, Vue 3, Nuxt 3, Next.js, TailwindCSS, and Python. Integrated APIs include Stripe, Twilio, SendGrid, the ChatGPT API, and the Claude API. Q: How do I contact Simon Dziak? A: Email simon.dziak@gmail.com for personal matters or szymon@app369.com for work inquiries. Phone (561) 606-8479. He also replies on LinkedIn at linkedin.com/in/szymondziak and on X as @SzymonDziak. Q: What languages does Simon Dziak speak? A: Polish and English, both native. The site publishes the same content in both languages at simondziak.com (English) and szymondziak.com (Polish). --- ## Experience — Q&A Q: How many apps has Simon Dziak shipped? A: Over 150 apps delivered end-to-end across iOS, Android, MacOS, and the web since 2018. Clients include BILSTEIN USA, Chicago Pneumatic, Artificial Grass Masters, SALT. Fine Jewelry, Gavalina, and many service-business founders. Q: What is Simon Dziak’s education? A: BA in Computer Science from the University of Florida (2020–2021, Gainesville, FL) after an Associates in Computer Science from Santa Fe College (2018–2020, Honors Program). Full-time at App369 since January 2020. Q: Does Simon Dziak take on freelance or contract work? A: Yes. App369 takes on a small number of client engagements at a time — mostly Flutter and full-stack product builds for service-business founders and enterprise clients. Email szymon@app369.com with a short brief to start a conversation. Q: What are Simon Dziak’s current focus areas? A: Claude Code agents for the Flutter SDLC, iOS 26 Liquid Glass adaptive UI in Flutter, and generative engine optimization (GEO) — how AI search rewrites SEO. Writing regularly at app369.com and here under /writing. --- ## Colophon — notes on this site — https://simondziak.com/writing/colophon Published 2026-04-22. How this site was built, why it exists in two languages, and the small choices behind the design. This site runs at two addresses — simondziak.com (English, cyan accent) and szymondziak.com (Polish, amber accent) — served from one Astro 5 + Tailwind v4 codebase on Firebase Hosting. Content is mirrored via `hreflang`, locale picked by domain, and monolingual on each side so there are no `/en/` or `/pl/` URL prefixes. This site has two addresses and one soul. Type `simondziak.com` and you'll land on the English version. Type `szymondziak.com` and you'll land on the Polish one. Same content, same voice, different accent — both literally and chromatically. ## Why two My passport has one name. My family has another. `Szymon` is the Polish form, `Simon` is what Americans end up calling me after two tries. I grew up bouncing between both, and for a long time my websites and profiles had to pick a side. This one doesn't. The domain you type decides the default language and the accent color. Cyan for English, amber for Polish. The logotype always reads `Simon⁄Szymon Dziak` — the active half lit up, the other half ghosted — so whichever version you're on, the other one's visible just underneath. Flip between them with the `EN/PL` toggle. Both domains are indexed independently on Google. `hreflang` tells search engines they're translations of each other, not duplicates. If you find me in English and share the link, a Polish friend can click it and read the same page in their language — same slug, same images, different words. ## Stack Astro 5 for the framework. Tailwind v4 via `@tailwindcss/vite` for styling (with a CLI pre-compile step because the Astro integration didn't cooperate). MDX for writing. Firebase Hosting for serving — one Firebase project, two Hosting sites, each built with a different `SITE_LOCALE` env var. Both builds come from the same source; the only difference is which language's content subtree gets loaded. A pre-build script symlinks `src/pages` to `src/sites//pages` so each deploy only emits the routes that make sense for that domain. English gets `/projects`, `/writing`, `/now`, `/about`. Polish gets `/projekty`, `/pisanie`, `/teraz`, `/o-mnie`. No `/en/` or `/pl/` URL prefixes — each domain is monolingual in its canonical form, and the toggle is a genuine cross-domain navigation. ## Design Dev-craft minimalism, in the rauno.me / paco.me / leerob.io lineage. Dark base (`#0a0a0a`), monospace for accents, Inter for body, everything sized in the text-rhythm rather than pixel round-numbers. The only chromatic motif is the accent: cyan on English, amber on Polish. Small things: the footer strip spells out `· s · z · c · l ·` on EN and `· ś · ż · ć · ł ·` on PL. The 404 page hides a huge `S` (or `Ś`) in the background. Press the `~` key anywhere on EN and the body text briefly blooms its Polish diacritics. ## Colors I keep - Base `#0a0a0a` - Ink `#e8e8e8`, muted `#999`, dim `#666` - Rule `#1f1f1f` - Accent EN `#7dd3fc` (cyan) - Accent PL `#ffd166` (amber) That's it. No other chromatic noise. --- ## Generative engine optimization: notes from the first 90 days — https://simondziak.com/writing/geo-first-90-days Published 2026-04-20. What actually moved the needle when I optimized this site for AI search — and what was a waste of time. GEO means structuring your site so AI models can read, cite, and summarize it accurately. Five things moved the needle: llms.txt, FAQPage schema, a rich JSON-LD graph, a robots.txt that explicitly welcomes AI crawlers, and answer-first TLDRs on every essay. Keyword stuffing did nothing. Generic "thought leadership" copy did nothing. SEO as I learned it was about signals. Backlinks, keyword density, crawl budget. You optimized for a ranking algorithm that mostly cared about what other pages thought of yours. Generative engine optimization is about something different. When ChatGPT, Perplexity, or Claude answers a question, it doesn't rank pages — it synthesizes information. The question isn't "do I rank?" It's "am I cited?" and more specifically: "can the model accurately represent what I do?" That reframe changes what you build. ## What GEO actually means A generative engine reads your site the way a researcher reads a paper. It wants structure, clear claims, and evidence. It doesn't care about your keyword density. It cares whether it can extract a usable fact from your page in under five seconds. The output isn't a blue link in a SERP. It's a sentence in an AI answer: "According to Simon Dziak, the best approach to..." or a citation in a Perplexity response. To earn that, your content needs to be crawlable, parseable, and actually worth citing. Most sites aren't. They're designed for humans reading at leisure, not for models skimming at inference speed. ## The five things that moved the needle **1. llms.txt and llms-full.txt** The `llms.txt` spec (proposed by Jeremy Howard) gives AI crawlers a clean, flat-text map of your site. I added both files at the root: `llms.txt` with a short site summary and links to key pages, `llms-full.txt` with the full text of every page concatenated. Models that support the spec can read everything in one request instead of crawling page by page. Perplexity started citing simondziak.com in answers about Flutter development within two weeks of adding these files. **2. FAQPage schema with answer-first copy** `FAQPage` JSON-LD is one of the highest-signal schema types for GEO. I added it on every page that could answer a question. The key is that the answer text in the schema must be self-contained — the model will lift it verbatim. So I wrote every answer in the schema to work standalone: the question, then the answer in full, no "as discussed above." The structure in code is `@type: FAQPage` with a `mainEntity` array of `Question` objects, each with `name` (the question) and `acceptedAnswer.text` (the answer). Keep answers under 150 words. Longer than that and the model will paraphrase, which means it may introduce errors. **3. BreadcrumbList + a rich Person/Organization JSON-LD graph** I built a connected entity graph: `Person` linked to `Organization` (App369), with `sameAs` pointing at GitHub, LinkedIn, and both domains. `BreadcrumbList` on every page tells the model the exact path: Home → Essays → This Essay. `Article` schema on each essay links back to the `Person` as author. Connected entities matter because models learn relationships. A model that's been trained on enough structured data will associate "Simon Dziak" with "App369" with "Flutter" without needing to see all three words on the same page. The graph does that association work. **4. robots.txt that explicitly welcomes AI crawlers** The default `User-agent: *` allows crawlers but doesn't tell AI crawlers they're welcome. I added explicit `Allow` rules for GPTBot, ClaudeBot, PerplexityBot, OAI-SearchBot, Anthropic-AI, and Google-Extended. More importantly, I added a `Sitemap` directive pointing at the full sitemap, and an `llms-full.txt` reference in the site's ``. Some crawlers check robots.txt before anything else — if it's silent on their user-agent, they default conservative. **5. Answer-first TLDR blocks on every essay** Every essay on this site now opens with a `` block — a 2-4 sentence summary that could stand alone as a complete answer. This is GEO and accessibility at the same time. A model skimming my essay for a citation will find a clean, self-contained answer in the first 100 words. It doesn't have to infer what I'm saying from the middle of a paragraph. The format matters: lead with the claim, follow with the evidence, end with the implication. Same structure as a well-cited academic abstract. Models are trained on a lot of academic text. ## What didn't move Keyword stuffing. I tried denser usage of "Flutter developer Miami" and similar phrases. No measurable change in AI citations. Models don't weight raw keyword frequency the way search crawlers do. Generic "thought leadership" copy. Paragraphs about "helping businesses succeed through technology" and similar boilerplate. Models ignore it. It's not specific enough to cite and not credible enough to trust. Excessive internal linking. I spent time building a deep internal link graph — every essay mentioning a project would link to that project. It helped traditional SEO slightly. It did nothing measurable for GEO. Internal links don't help a model understand your entities — structured schema data does. ## What I'm doing differently now I write every piece of content with a question in mind: "what is someone asking when they find this?" The TLDR answers that question directly. The body earns the answer. I treat schema as content, not markup. The text in `FAQPage` and `Article` schema is as important as the body copy — maybe more, because it's the part the model is most likely to read first. I'm also less obsessed with traffic metrics. The GEO signal I care about is citations: does Perplexity mention this site when someone asks about Flutter development or Miami app studios? That's harder to measure than a ranking position, but it's the actual outcome I want. The honest summary: GEO is mostly good content strategy with structured data on top. The sites that will win at it aren't the ones with the cleverest technical setup — they're the ones with clear, specific, credible content that a model can summarize without making things up. --- ## Why 369 — https://simondziak.com/writing/why-369 Published 2026-04-18. Every brand I build has 369 in the name. Here's why that's not an accident and what it costs me to keep it that way. The 369 suffix started as a name I liked for my first project in 2018 and became a deliberate brand signal: everything under 369 is connected, and anything that isn't mine doesn't carry the suffix. That constraint keeps the portfolio legible and keeps me accountable. People ask about the number often enough that it's worth a short answer. ## How it started In 2018 I was building my first studio and I needed a name. I'd been reading about Tesla's fixation on 3, 6, and 9 — he called them the key to the universe, which is the kind of claim that either sounds ridiculous or magnetic depending on your mood. I was in a magnetic mood. The name App369 stuck. I didn't intend to build a brand family around it. I intended to name one company. ## What happened instead By 2020 I was full-time on App369 and shipping enough to see patterns. Every service-business client I worked with eventually needed the same internal ops layer: a place to quote jobs, send proposals, invoice clients, collect payments, organize projects and tasks, collaborate across the team, automate repetitive work — and more. I kept building it from scratch for them. So I built it once for everyone — Workspace369. A unified workspace to run your whole solo-entrepreneur business or agency is the single most important piece of staying successful — the organization and structure are what let you perform at the master level. Around the same time I realized that every new Flutter project started with the same bootstrapping: wire up Firebase, add Stripe, connect RevenueCat, hook up auth. Two weeks of setup before one real line of product code. I packaged that setup — Template369. By the time I had three products with 369 in the name the suffix was no longer incidental. It was a statement: these things are related, they come from the same hand, and they're built the same way. ## The discipline it enforces Keeping the suffix means keeping the commitment. I can't put 369 on something I built carelessly or handed off without care. The name is a check on my own standards. It also keeps the portfolio legible. A client looking at App369 can find Workspace369 and Template369 without explanation. The naming does the work of saying "same person, same approach, same quality bar." The cost is inflexibility. I can't sell a brand with 369 in the name. I can't white-label it away. It's tied to me, which is either a liability or an asset depending on how well I do the work. So far I've decided it's an asset. Ask me again in ten years. --- ## Claude Code agents, wired up for Flutter — https://simondziak.com/writing/flutter-claude-code Published 2026-03-18. What happens when you stop treating the AI as a better autocomplete and start treating it as a teammate who can run the toolchain. Claude Code agents turn Flutter's existing toolchain (`flutter analyze`, `flutter test`, `dart format`) into the feedback signal for an AI teammate. Keep short, imperative recipes in `.claude/skills/` — one per SDLC step — and the agent writes the boring code while you think about the hard parts. For most of my career the accepted shape of "programmer tools" was: you type, the editor helps a little, the compiler yells a lot. The loop was human-driven and fast because the compiler was fast. Claude Code changes the shape. The AI isn't in the gutter of my editor autocompleting names — it's running the toolchain. It reads the repo, runs `flutter analyze`, picks a failing test, reads the test, reads the code under test, proposes a patch, applies it, reruns. That's not autocomplete. That's a teammate. ## Where this broke my Flutter workflow (in a good way) The first thing I noticed was that the agent is *boring-good* at the boring parts. Adding a new screen, wiring routing, plumbing a model through a repository into a view — the kind of work that used to eat a Tuesday morning now happens while I'm refilling coffee. The second thing I noticed was the opposite: on genuinely tricky things the agent is polite about uncertainty. It writes a test, runs it, reads the output, comes back and says "the test proves the bug is in the serializer, not the widget; I think the fix is here — want me to try?" That's a better conversation than I had with myself before. ## The recipe format Everything gets better when you give the agent shape. I keep a `.claude/skills/` directory in every Flutter repo with short, imperative markdown files — each one a "recipe" for a specific SDLC step. One for adding a feature. One for fixing a bug. One for shipping a release. Each recipe tells the agent which commands to run, in what order, and what counts as "done." A fix recipe might look like: (1) reproduce the bug with a failing test; (2) make the test pass with the smallest patch; (3) run the full suite; (4) run the linter; (5) commit with a Conventional Commits message. The agent follows that flow and I get to review a pull request shaped exactly how I'd shape it myself. The trick is that the recipes are short. Long recipes rot. If a recipe has more than a dozen bullets I split it in half. ## What I've stopped doing I used to manually keep a TODO list in my head for every feature. Now I dispatch the agent and do something else. When it comes back I read the diff. I used to context-switch between a dozen tabs. Now the agent reads the docs for me and paraphrases. I spot-check when the answer matters. I used to write scaffolding code. Now I write the contract — interfaces, schemas, test names — and the agent fills in the implementation that satisfies it. I still write the hard parts by hand. The parts where I need to think through a subtle invariant or a tricky cache. The AI isn't better at those yet. But it's freed up so much of the easy-work time that I can actually think about the hard parts instead of being numb from having fought through a thousand tiny ceremonies first. ## What I'm still figuring out The interesting failure mode isn't "AI writes bad code." It's "AI writes fine code for the wrong question." You give it a bug report that said "the button doesn't work" and it adds a disabled state check, when the real issue is that a prior refactor made the tap event handler unreachable. The fix works for the reported symptom and hides the underlying problem. The antidote is being honest about what the bug actually is. Which is good practice anyway. It just becomes more expensive to skip. ## If you want to try this Put this in your repo and go: a `.claude/skills/` folder with `fix.md`, `feature.md`, `ship.md`. Each one short. Each one telling the agent what "done" means for that kind of task. Trust your linter and your test suite — they're the agent's feedback signal, and if they're weak the agent will drift. The better your tools, the better your agent. Flutter happens to have great tools. `flutter analyze`, `flutter test`, `dart format`, `dart fix`. Plug those into the agent and the quality bar is self-enforcing. The actual change for me wasn't about code. It was about what I do all day. Less typing. More thinking. More shipping.