PageSourceSearch

https://aexol.com/posts/full-stack-graphql/

html aexol.com collected 2026-10-02 14:53:59 UTC 50,342 bytes, 215 lines download raw bytes

1<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>Full-Stack GraphQL Type Safety: Axolotl, Zeus &amp; Vite Guide</title><meta name="description" content="Achieve full-stack type safety with Axolotl, Zeus, and Vite. Learn to secure your GraphQL APIs and React apps with TypeScript from schema to UI."/><link rel="canonical" href="https://aexol.com/posts/full-stack-graphql/"/><meta name="robots" content="index, follow, max-video-preview:-1, max-image-preview:large, max-snippet:-1"/><meta name="googlebot" content="index, follow"/><link rel="shortcut icon" type="image/x-icon" href="/favicon.ico"/><link rel="icon" type="image/png" href="/images/favicon-32x32.png" sizes="32x32"/><link rel="icon" type="image/png" href="/images/favicon-16x16.png" sizes="16x16"/><link rel="apple-touch-icon" href="/images/apple-touch-icon.png"/><meta name="keywords" content="AI software house, custom software development, React Native, GraphQL, TypeScript, LLM integration, AI development, Polish software house, software development Poland, aexol"/><meta name="author" content="AEXOL"/><meta name="theme-color" content="#0f172a"/><meta property="og:type" content="website"/><meta property="og:site_name" content="aexol.com"/><meta property="og:locale" content="en_US"/><meta property="og:image" content="https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/blogpost/generated-image-november-29-2025-1-42-pm-1765205203487.jpeg"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:type" content="image/png"/><meta property="og:title" content="Full-Stack GraphQL Type Safety: Axolo..."/><meta property="og:description" content="Achieve full-stack type safety with Axolotl, Zeus, and Vite. Learn to secure your GraphQL APIs and React apps with TypeScript from schema to UI."/><meta property="og:url" content="https://aexol.com/posts/full-stack-graphql/"/><meta property="article:publisher" content="https://www.facebook.com/profile.php?id=61563813375531"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:site" content="@aexol"/><meta name="twitter:creator" content="@aexol"/><meta name="twitter:title" content="Full-Stack GraphQL Type Safety: Axolotl, Zeus &amp; Vite Guide"/><meta name="twitter:description" content="Achieve full-stack type safety with Axolotl, Zeus, and Vite. Learn to secure your GraphQL APIs and React apps with TypeScript from schema to UI."/><meta name="twitter:image" content="https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/blogpost/generated-image-november-29-2025-1-42-pm-1765205203487.jpeg"/><link rel="alternate" hrefLang="pl" href="https://aexol.com/pl/posts/full-stack-graphql/"/><link rel="alternate" hrefLang="en" href="https://aexol.com/posts/full-stack-graphql/"/><link rel="alternate" hrefLang="x-default" href="https://aexol.com/posts/full-stack-graphql/"/>
1<script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","@id":"https://aexol.com/#organization","name":"AEXOL","url":"https://aexol.com","logo":"https://aexol.com/aexol-logo.png","description":"AI-powered software house specializing in React Native, GraphQL, TypeScript, and LLM integration. We build software products without the agency fog.","foundingDate":"2018","founders":[{"@type":"Person","name":"Aexol Team"}],"address":{"@type":"PostalAddress","addressLocality":"Białystok","addressCountry":"PL"},"contactPoint":{"@type":"ContactPoint","contactType":"sales","email":"[email protected]"},"sameAs":["https://www.facebook.com/profile.php?id=61563813375531","https://clutch.co/profile/aexol"],"aggregateRating":{"@type":"AggregateRating","ratingValue":"4.9","ratingCount":"26","bestRating":"5"}}</script>
1<meta name="next-head-count" content="36"/>
1<script id="Cookiebot" src="https://consent.cookiebot.com/uc.js" data-cbid="8b696021-9f40-479e-abc5-4485a71edcf1" data-blockingmode="auto" type="text/javascript"></script>
1 <link rel="preload" href="/_next/static/media/8e9860b6e62d6359-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/css/93f6bfceb2e971ed.css" as="style"/><link rel="stylesheet" href="/_next/static/css/93f6bfceb2e971ed.css" data-n-g=""/><noscript data-n-css=""></noscript>
1<script defer="" nomodule="" src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script>
1<script src="/_next/static/chunks/webpack-7daa6012f2af4277.js" defer=""></script>
1<script src="/_next/static/chunks/framework-2c16ac744b6cdea6.js" defer=""></script>
1<script src="/_next/static/chunks/main-b4f2603581d39a90.js" defer=""></script>
1<script src="/_next/static/chunks/pages/_app-bd75134f52e23b1f.js" defer=""></script>
1<script src="/_next/static/chunks/36d2f571-91eaf09f099111d5.js" defer=""></script>
1<script src="/_next/static/chunks/854-885b603865438fa4.js" defer=""></script>
1<script src="/_next/static/chunks/927-7334095b3492deaf.js" defer=""></script>
1<script src="/_next/static/chunks/188-0314b5ef88477a93.js" defer=""></script>
1<script src="/_next/static/chunks/734-09da704e8d80f874.js" defer=""></script>
1<script src="/_next/static/chunks/428-4669e2a881d26474.js" defer=""></script>
1<script src="/_next/static/chunks/pages/posts/%5Bslug%5D-9003d9159da936a4.js" defer=""></script>
1<script src="/_next/static/zmgWC04bnd70evER7bsVb/_buildManifest.js" defer=""></script>
1<script src="/_next/static/zmgWC04bnd70evER7bsVb/_ssgManifest.js" defer=""></script>
1<style id="__jsx-892992001">html{font-family:'__Inter_755f84', '__Inter_Fallback_755f84'}</style></head><body><div id="__next"><div class="relative flex flex-col min-h-screen bg-background text-foreground"><div class="fixed inset-0 pointer-events-none overflow-hidden"><div class="absolute top-0 left-1/4 w-[800px] h-[600px] bg-primary/5 rounded-full blur-[120px] animate-float opacity-30"></div><div class="absolute bottom-0 right-1/4 w-[600px] h-[400px] rounded-full blur-[100px] opacity-20 animate-float" style="background:radial-gradient(circle, rgba(232,159,46,0.15) 0%, transparent 70%);animation-delay:-3s"></div><div class="absolute inset-0 ai-grid-bg opacity-20"></div></div><div class="relative w-full bg-emerald-400 text-emerald-950"><div class="absolute inset-0 opacity-30 pointer-events-none" style="background:linear-gradient(90deg, rgba(255,255,255,0.12) 0%, transparent 35%, transparent 65%, rgba(255,255,255,0.12) 100%)"></div><div class="container relative py-2 flex items-center justify-center gap-3 text-center"><span class="hidden sm:block flex-shrink-0 text-sm" role="img" aria-label="Robot">🤖</span><p class="text-xs sm:text-sm font-medium">Focus on vision, not fighting errors. Use the most powerful coding agents.<!-- --> <a target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-1 underline decoration-emerald-950/40 hover:decoration-emerald-950 underline-offset-2 font-semibold group" href="https://aexol.ai">Try aexol.ai<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="w-3 h-3 group-hover:translate-x-0.5 transition-transform" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg></a></p></div></div><nav class="select-none sticky top-0 z-50 w-full transition-all duration-300 bg-transparent"><div class="container flex items-center justify-between py-4"><a class="flex items-center gap-2" href="/"><span class="text-2xl font-bold tracking-tight ai-gradient-text">AEXOL</span></a><div class="hidden lg:flex items-center gap-8"><div class="flex items-center gap-6"><div class="relative"><button type="button" class="flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors py-2 cursor-pointer">Our work<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="text-xs" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div><div class="relative"><button type="button" class="flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors py-2 cursor-pointer">Services<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="text-xs" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div><a class="relative text-sm font-medium text-muted-foreground hover:text-foreground transition-colors py-2" href="/pricing/">Pricing</a><div class="relative"><button type="button" class="flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors py-2 cursor-pointer">Industries<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="text-xs" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div><div class="relative"><button type="button" class="flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors py-2 cursor-pointer">Technologies<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="text-xs" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div><a class="relative text-sm font-medium text-muted-foreground hover:text-foreground transition-colors py-2" href="/resources-hub/">Resources Hub</a></div><a class="relative btn-primary" href="/contact/">Contact us</a></div><div class="block lg:hidden"><button class="block text-2xl" aria-label="Open menu" aria-expanded="false"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg></button></div></div></nav><main class="relative flex-1"><article class="content-container max-w-3xl pt-32 pb-20 md:pt-40 md:pb-28"><nav class="mb-8"><ol class="flex flex-wrap items-center text-sm text-muted-foreground"><li><a class="hover:text-foreground transition-colors" href="/">Home</a></li>
1<li class="mx-2 text-muted-foreground/50">/</li><li><a class="hover:text-foreground transition-colors" href="/resources-hub/">Recent articles</a></li></ol></nav><header class="mb-12"><h1 class="section-title mb-5 text-foreground">Full-Stack Type Safety with Axolotl, Zeus, and Vite</h1><div class="flex items-center text-sm text-muted-foreground"><time dateTime="2025-12-08">December 8, 2025</time><span class="mx-2 text-muted-foreground/50">•</span><span>by <!-- -->Artur Czemiel</span></div></header><div class="mb-12 rounded-xl overflow-hidden border border-white/5 shadow-2xl"><img src="https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/blogpost/generated-image-november-29-2025-1-42-pm-1765205203487.jpeg" alt="Full-Stack Type Safety with Axolotl, Zeus, and Vite" class="w-full h-auto"/></div><div class="   flex flex-col w-full gap-[0.5rem] font-[300] text-foreground   text-base leading-[1.5rem]   lg:text-[1.125rem] lg:leading-[1.75]   [&amp;&gt;*]:mb-6   [&amp;&gt;h2]:text-2xl [&amp;&gt;h2]:font-semibold [&amp;&gt;h2]:mt-12 [&amp;&gt;h2]:mb-4 [&amp;&gt;h2]:text-foreground   [&amp;&gt;h3]:text-xl [&amp;&gt;h3]:font-medium [&amp;&gt;h3]:mt-8 [&amp;&gt;h3]:mb-4 [&amp;&gt;h3]:text-foreground   [&amp;&gt;p]:max-w-[70ch]   [&amp;&gt;ul]:list-disc [&amp;&gt;ul]:pl-6   [&amp;&gt;ol]:list-decimal [&amp;&gt;ol]:pl-6   [&amp;&gt;ul&gt;li]:mb-2 [&amp;&gt;ol&gt;li]:mb-2   [&amp;&gt;blockquote]:border-l-4 [&amp;&gt;blockquote]:border-primary/40 [&amp;&gt;blockquote]:pl-4 [&amp;&gt;blockquote]:italic [&amp;&gt;blockquote]:text-muted-foreground   [&amp;&gt;pre]:bg-white/5 [&amp;&gt;pre]:p-4 [&amp;&gt;pre]:rounded-md [&amp;&gt;pre]:overflow-x-auto [&amp;&gt;pre]:text-foreground   [&amp;&gt;p&gt;code]:bg-white/10 [&amp;&gt;p&gt;code]:px-1 [&amp;&gt;p&gt;code]:rounded [&amp;&gt;p&gt;code]:text-foreground   [&amp;&gt;p&gt;a]:text-primary [&amp;&gt;p&gt;a]:underline hover:[&amp;&gt;p&gt;a]:text-primary/80   [&amp;&gt;hr]:my-8 [&amp;&gt;hr]:border-t [&amp;&gt;hr]:border-white/10   [&amp;_strong]:font-bold [&amp;_b]:font-bold   "><h1>Full-Stack Type Safety with Axolotl, Zeus, and Vite</h1>
2<p>I've been building GraphQL APIs for years, and the biggest pain has always been keeping types in sync. You write your schema, manually create TypeScript types for resolvers, generate client types, and hope nothing drifts. One typo in a resolver return type and you're debugging runtime errors.</p>
3<p>This example shows a different approach - true end-to-end type safety from schema to React components, running on a single server.</p>
4<h2>The Setup</h2>
5<p>The <code>yoga-federated</code> example runs everything on one port:</p>
6<ul>
7<li><strong>Backend</strong>: Express + GraphQL Yoga with Axolotl-generated types</li>
8<li><strong>Frontend</strong>: React + Vite with Zeus-generated GraphQL client</li>
9<li><strong>Both</strong>: Same server, same origin</li>
10</ul>
11<p>http://localhost:4002/         -&gt; React Frontend (SSR)</p>
12<p>http://localhost:4002/graphql  -&gt; GraphQL Playground</p>
13<p>In development, Vite runs as Express middleware for HMR. In production, Express serves the built frontend. One deployment, zero CORS config.</p>
14<h2>The @resolver Directive</h2>
15<p>Here's the schema:</p>
16<pre><code class="language-gql">type Todo {
17  _id: String!
18  content: String!
19  done: Boolean
20}
21
22type AuthorizedUserMutation {
23  createTodo(content: String!, secret: Secret): String! @resolver
24  todoOps(_id: String!): TodoOps! @resolver
25}
26
27type Query {
28  user: AuthorizedUserQuery @resolver
29}
30</code></pre>
31<p>The <code>@resolver</code> directive marks which fields need implementation. Fields without it are auto-resolved from the parent object.</p>
32<pre><code class="language-gql">type Query {
33  user: AuthorizedUserQuery @resolver # ← needs code
34}
35
36type User {
37  _id: String! # ← resolved from parent
38  username: String! # ← resolved from parent
39}
40</code></pre>
41<p>This is what makes Axolotl work well with AI assistants. When Copilot or Cursor sees a schema, it knows exactly which fields need resolvers and which don't. No guessing.</p>
42<p>Prompt an AI with &quot;Implement all @resolver fields&quot; and it generates the right code because the schema is explicit about what needs implementation.</p>
43<p>Run <code>axolotl build</code> and you get typed models:</p>
44<pre><code class="language-ts">// Auto-generated src/models.ts
45export interface Todo {
46  _id: string;
47  content: string;
48  done?: boolean | undefined | null;
49}
50
51export type Models = {
52  ['AuthorizedUserMutation']: {
53    createTodo: {
54      args: {
55        content: string;
56        secret?: Secret | undefined | null;
57      };
58    };
59  };
60};
61</code></pre>
62<p>Write resolvers with full type inference:</p>
63<pre><code class="language-ts">// src/todos/resolvers/AuthorizedUserMutation/createTodo.ts
64import { createResolvers } from '../../axolotl.js';
65
66export default createResolvers({
67  AuthorizedUserMutation: {
68    createTodo: async ([source], { content }) =&gt; {
69      // TypeScript knows `content` is string
70      // TypeScript knows this must return string
71      const _id = Math.random().toString(8);
72      db.todos.push({ owner: src._id, content, _id });
73      return _id;
74    },
75  },
76});
77</code></pre>
78<p>Return a number instead of a string and TypeScript complains immediately.</p>
79<h2>Micro-Federation</h2>
80<p>The example splits schemas by domain:</p>
81<pre><code class="language-ts">src/
82├── todos/
83│   ├── schema.graphql
84│   └── resolvers/
85├── users/
86│   ├── schema.graphql
87│   └── resolvers/
88└── resolvers.ts
89</code></pre>
90<p>Axolotl merges them:</p>
91<pre><code class="language-ts">// src/resolvers.ts
92import { mergeAxolotls } from '@aexol/axolotl-core';
93import todosResolvers from '@/src/todos/resolvers/resolvers.js';
94import usersResolvers from '@/src/users/resolvers/resolvers.js';
95
96export default mergeAxolotls(todosResolvers, usersResolvers);
97</code></pre>
98<p>Types flow through the merge.</p>
99<h2>Frontend with Zeus</h2>
100<p>Zeus generates a typed GraphQL client from the schema:</p>
101<pre><code class="language-ts">// frontend/src/api.ts
102import { Chain } from '../../src/zeus/index';
103
104export const createGqlClient = (token?: string) =&gt; {
105  const headers: Record&lt;string, string&gt; = {
106    'Content-Type': 'application/json',
107  };
108  if (token) {
109    headers['token'] = token;
110  }
111  return Chain('/graphql', { headers });
112};
113</code></pre>
114<p>Queries are type-safe:</p>
115<pre><code class="language-ts">// frontend/src/hooks/useTodos.ts
116const fetchTodos = async () =&gt; {
117  const data = await gql()('query')({
118    user: {
119      todos: { _id: true, content: true, done: true },
120    },
121  });
122
123  // TypeScript knows data.user?.todos is Todo[]
124  if (data.user?.todos) {
125    setTodos(data.user.todos);
126  }
127};
128</code></pre>
129<p>Mutations too:</p>
130<pre><code class="language-ts">const createTodo = async (content: string) =&gt; {
131  await gql()('mutation')({
132    user: {
133      createTodo: [{ content }, true],
134    },
135  });
136};
137</code></pre>
138<p>The <code>[{ content }, true]</code>
138 syntax means: pass these arguments, return this field. TypeScript validates that <code>content</code> matches the schema.</p>
139<h2>Express + Vite on One Server</h2>
140<p>The whole stack runs on one Express server:</p>
141<pre><code class="language-ts">// src/index.ts
142async function startServer() {
143  const app = express();
144
145  // Mount GraphQL
146  const { yoga } = adapter({ resolvers, directives });
147  app.use('/graphql', yoga);
148
149  // Development: Vite middleware for HMR
150  if (!isProduction) {
151    const vite = await createViteServer({
152      server: { middlewareMode: true },
153      appType: 'custom',
154    });
155    app.use(vite.middlewares);
156  } else {
157    // Production: serve built assets
158    app.use(sirv(resolve(__dirname, '../dist/client')));
159  }
160
161  // SSR for all other routes
162  app.use('*all', async (req, res) =&gt; {
163    const { html } = await render(req.originalUrl);
164    res.send(html);
165  });
166}
167</code></pre>
168<p>You get:</p>
169<ul>
170<li>HMR in development</li>
171<li>SSR for SEO</li>
172<li>One deployment artifact</li>
173<li>No proxy config</li>
174</ul>
175<h2>The Type Flow</h2>
176<p>A todo travels through the system like this:</p>
177<ol>
178<li><strong>Schema</strong> defines <code>createTodo(content: String!): String!</code></li>
179<li><strong>Axolotl</strong> generates <code>args: { content: string }</code> for resolvers</li>
180<li><strong>Resolver</strong> uses <code>{ content }</code> with TypeScript support</li>
181<li><strong>Zeus</strong> generates client types from the same schema</li>
182<li><strong>React hook</strong> calls <code>createTodo: [{ content }, true]</code> with type checking</li>
183<li><strong>Response</strong> comes back typed</li>
184</ol>
185<p>Change the schema, run <code>axolotl build</code>, and TypeScript shows you what broke.</p>
186<h2>Try It</h2>
187<pre><code class="language-ts">cd examples/yoga-federated
188npm install
189npm run dev
190</code></pre>
191<p>Open http://localhost:4002:</p>
192<p><img src="https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/media/screenshot-login-1765204379116.png" alt=""></p>
193<p>Register and you're in and can create todos</p>
194<p><img src="https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/media/screenshot-todo-created-1765204389217.png" alt=""></p>
195<p>GraphQL Playground at http://localhost:4002/graphql:</p>
196<p><img src="https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/media/screenshot-playground-1765204385463.png" alt=""></p>
197<h2>What I Like About This</h2>
198<p>After using this pattern, a few things stand out:</p>
199<ol>
200<li><strong>Schema changes propagate everywhere</strong> - modify a field, run build, TypeScript tells you what broke on both backend and frontend</li>
201<li><strong>AI assistants actually help</strong> - the <code>@resolver</code> directive means Copilot knows what to implement without explaining the architecture</li>
202<li><strong>One <code>npm run dev</code></strong> - no separate terminal for frontend, no proxy config, no CORS debugging</li>
203<li><strong>SSR just works</strong> - good for SEO if you need it</li>
204</ol>
205<p>The tradeoff is coupling - frontend and backend deploy together. For most projects that's fine. If you need independent scaling, split them later.</p>
206<h2>Links</h2>
207<ul>
208<li><a href="https://axolotl.aexol.com">Axolotl Documentation</a></li>
209<li><a href="https://zeus.aexol.com">GraphQL Zeus Documentation</a></li>
210<li><a href="https://github.com/aexol-studio/axolotl/tree/main/examples/yoga-federated">Example Source Code</a></li>
211</ul>
212<hr>
213<p><em>Built with Axolotl + GraphQL Yoga + Zeus by</em> <a href="https://aexol.com">Aexol Studio</a></p>
214</div></article><section class="section-padding relative overflow-hidden"><div class="absolute inset-0 ai-grid-bg opacity-60"></div><div class="absolute inset-0 pointer-events-none hidden lg:block"><div class="absolute left-0 top-1/2 -translate-y-1/2 w-[42rem] h-[34rem] bg-cover bg-center opacity-[0.18] mix-blend-luminosity" style="background-image:url(/deliverky_web.png);mask-image:radial-gradient(ellipse 70% 80% at 25% 50%, black 0%, transparent 75%);-webkit-mask-image:radial-gradient(ellipse 70% 80% at 25% 50%, black 0%, transparent 75%)"></div><div class="absolute right-0 top-1/2 -translate-y-1/2 w-[42rem] h-[34rem] bg-cover bg-center opacity-[0.18] mix-blend-luminosity" style="background-image:url(/magiczny_web.png);mask-image:radial-gradient(ellipse 70% 80% at 75% 50%, black 0%, transparent 75%);-webkit-mask-image:radial-gradient(ellipse 70% 80% at 75% 50%, black 0%, transparent 75%)"></div><div class="absolute inset-0 opacity-30 mix-blend-color" style="background:linear-gradient(90deg, rgba(232,159,46,0.35) 0%, transparent 35%, transparent 65%, rgba(232,159,46,0.35) 100%)"></div></div><div class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[60rem] h-[40rem] rounded-full blur-[120px] opacity-30 pointer-events-none" style="background:radial-gradient(circle at 50% 50%, rgba(232,159,46,0.4) 0%, transparent 60%)"></div><div class="content-container max-w-5xl text-center relative"><div class="glass-card ai-gradient-border p-10 md:p-16 lg:py-20 lg:px-24 relative overflow-hidden" style="opacity:0;transform:translateY(20px) translateZ(0)"><div class="absolute inset-x-0 top-0 h-px opacity-60 pointer-events-none" style="background:linear-gradient(90deg, transparent, rgba(232,159,46,0.7), transparent)"></div><span class="badge mb-6 inline-flex" style="opacity:0;transform:translateY(10px) translateZ(0)"><span class="w-1.5 h-1.5 rounded-full bg-primary animate-pulse"></span>Ready to start?</span><h2 class="section-title mb-4 text-balance" style="opacity:0;transform:translateY(15px) translateZ(0)">Let&#x27;s talk about your project.</h2><p class="section-subtitle mx-auto mb-10 max-w-2xl" style="opacity:0;transform:translateY(10px) translateZ(0)">Free consultation and quote within 48h. No strings attached.</p><div style="opacity:0;transform:translateY(10px) translateZ(0)"><a class="btn-primary animate-glow-pulse group text-base px-7 py-3.5" href="/contact/">Contact us<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="group-hover:translate-x-0.5 transition-transform" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg></a></div><div class="mt-10 pt-8 border-t border-white/5 flex flex-col sm:flex-row items-center justify-center gap-4 text-sm text-muted-foreground" style="opacity:0"><div class="flex items-center gap-2"><div class="flex text-primary"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="fill-current w-3.5 h-3.5" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="fill-current w-3.5 h-3.5" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="fill-current w-3.5 h-3.5" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="fill-current w-3.5 h-3.5" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="fill-current w-3.5 h-3.5" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg></div><span class="font-medium text-foreground">5.0</span>
214<span class="text-muted-foreground/70">on Clutch</span></div><span class="hidden sm:inline text-muted-foreground/30">•</span><div class="flex items-center gap-2"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="w-3.5 h-3.5 text-primary" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg><span>Free quote in 48h</span></div><span class="hidden sm:inline text-muted-foreground/30">•</span><div class="flex items-center gap-2"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="w-3.5 h-3.5 text-primary" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect><rect x="9" y="9" width="6" height="6"></rect><line x1="9" y1="1" x2="9" y2="4"></line><line x1="15" y1="1" x2="15" y2="4"></line><line x1="9" y1="20" x2="9" y2="23"></line><line x1="15" y1="20" x2="15" y2="23"></line><line x1="20" y1="9" x2="23" y2="9"></line><line x1="20" y1="14" x2="23" y2="14"></line><line x1="1" y1="9" x2="4" y2="9"></line><line x1="1" y1="14" x2="4" y2="14"></line></svg><span>AI-era team</span></div></div></div></div></section></main><footer class="relative"><div class="h-px bg-ai-gradient opacity-30"></div><div class="relative bg-card/50 backdrop-blur-sm"><div class="absolute inset-0 ai-grid-bg opacity-50 pointer-events-none"></div><div class="container relative py-16 md:py-24"><div class="grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-8 mb-16"><div class="lg:col-span-4"><a class="inline-block mb-6" href="/"><span class="text-2xl font-bold ai-gradient-text">AEXOL</span></a><p class="text-muted-foreground text-sm leading-relaxed max-w-xs mb-8">AI-powered software house. We build, you scale — no agency fog, just working code and clear scope.</p><div class="flex flex-col gap-3 w-fit"><div class="glass-card px-3 py-1.5 text-xs text-muted-foreground inline-flex items-center gap-1.5"><span class="w-1.5 h-1.5 rounded-full bg-green-400 animate-pulse"></span>Available for projects</div><a target="_blank" rel="noopener noreferrer" class="inline-flex w-fit items-center gap-2 text-sm font-medium text-primary hover:text-primary/80 transition-colors" href="https://aexol.ai">Try aexol.ai<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="text-xs" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><line x1="7" y1="17" x2="17" y2="7"></line><polyline points="7 7 17 7 17 17"></polyline></svg></a></div></div><div class="lg:col-span-8"><div class="grid grid-cols-2 sm:grid-cols-3 gap-8"><div><h4 class="text-sm font-semibold mb-4 text-foreground">Services</h4><ul class="space-y-2.5"><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/services/web-development/">Web Apps</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/services/mobile-development/">Mobile Apps</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/services/mvp-development/">MVP Development</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/services/ai-services/">AI &amp; Automation</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/pricing/">Pricing</a></li></ul></div><div><h4 class="text-sm font-semibold mb-4 text-foreground">AEXOL™ Stack</h4><ul class="space-y-2.5"><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/technologies/sdl/">SDL</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/technologies/studio/">Studio</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/technologies/spectral/">Spectral</a></li></ul></div><div><h4 class="text-sm font-semibold mb-4 text-foreground">Industries</h4><ul class="space-y-2.5"><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/industries/ecommerce/">E-commerce</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/industries/saas/">SaaS</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/industries/govtech/">GovTech</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/industries/influencer-apps/">Influencer Apps</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/industries/b2b-apps/">B2B Apps</a></li></ul></div><div><h4 class="text-sm font-semibold mb-4 text-foreground">Resources</h4><ul class="space-y-2.5"><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/resources-hub/?tab=articles">Articles</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/resources-hub/?tab=products">Products</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/resources-hub/?tab=open_source">Open-source</a></li><li><a class="text-sm text-muted-foreground hover:text-foreground transition-colors inline-flex items-center gap-1 group" href="/resources-hub/?tab=ebooks">E-Books</a></li></ul></div></div></div></div><div class="pt-8 border-t border-white/5 flex flex-col sm:flex-row gap-4 items-start sm:items-center justify-between"><div class="space-y-2">
214<p class="text-xs text-muted-foreground/60 leading-relaxed">Mławska 4/U7</p><p class="text-xs text-muted-foreground/60 leading-relaxed">15-411 Białystok</p><p class="text-xs text-muted-foreground/60 leading-relaxed">Poland, EU</p><p class="text-xs text-muted-foreground/60 leading-relaxed">KRS: 0000602817</p><p class="text-xs text-muted-foreground/60 leading-relaxed">REGON: 363749060</p><p class="text-xs text-muted-foreground/60 leading-relaxed">VAT ID: PL5423253283</p></div><div class="flex flex-col sm:items-end gap-2"><p class="text-xs text-muted-foreground/60">PL/EN: +48 887 723 965</p><p class="text-xs text-muted-foreground/60">PL/FR: +48 530 760 594</p><a class="text-sm text-primary hover:text-primary/80 transition-colors" href="/cdn-cgi/l/email-protection#8ae5ecece3e9efcaebeff2e5e6a4e9e5e7"><span class="__cf_email__" data-cfemail="107f7676797375507175687f7c3e737f7d">[email&#160;protected]</span></a></div></div></div></div></footer></div></div>
vendor: 108 bytes, line 214
214<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
214<script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"post":{"title":"Full-Stack Type Safety with Axolotl, Zeus, and Vite","description":"I've been building GraphQL APIs for years, and the biggest pain has always been keeping types in sync. You write your schema, manually create TypeScript types for resolvers, generate client types, and hope nothing drifts. One typo in a resolver return type and you're debugging runtime errors.","date":"2025-12-08","slug":"full-stack-graphql","locale":"en","content":"# Full-Stack Type Safety with Axolotl, Zeus, and Vite\n\nI've been building GraphQL APIs for years, and the biggest pain has always been keeping types in sync. You write your schema, manually create TypeScript types for resolvers, generate client types, and hope nothing drifts. One typo in a resolver return type and you're debugging runtime errors.\n\nThis example shows a different approach - true end-to-end type safety from schema to React components, running on a single server.\n\n## The Setup\n\nThe `yoga-federated` example runs everything on one port:\n\n* **Backend**: Express + GraphQL Yoga with Axolotl-generated types\n* **Frontend**: React + Vite with Zeus-generated GraphQL client\n* **Both**: Same server, same origin\n\nhttp://localhost:4002/         -\u003e React Frontend (SSR)\n\nhttp://localhost:4002/graphql  -\u003e GraphQL Playground\n\nIn development, Vite runs as Express middleware for HMR. In production, Express serves the built frontend. One deployment, zero CORS config.\n\n## The @resolver Directive\n\nHere's the schema:\n\n```gql\ntype Todo {\n  _id: String!\n  content: String!\n  done: Boolean\n}\n\ntype AuthorizedUserMutation {\n  createTodo(content: String!, secret: Secret): String! @resolver\n  todoOps(_id: String!): TodoOps! @resolver\n}\n\ntype Query {\n  user: AuthorizedUserQuery @resolver\n}\n```\n\nThe `@resolver` directive marks which fields need implementation. Fields without it are auto-resolved from the parent object.\n\n```gql\ntype Query {\n  user: AuthorizedUserQuery @resolver # ← needs code\n}\n\ntype User {\n  _id: String! # ← resolved from parent\n  username: String! # ← resolved from parent\n}\n```\n\nThis is what makes Axolotl work well with AI assistants. When Copilot or Cursor sees a schema, it knows exactly which fields need resolvers and which don't. No guessing.\n\nPrompt an AI with \"Implement all @resolver fields\" and it generates the right code because the schema is explicit about what needs implementation.\n\nRun `axolotl build` and you get typed models:\n\n```ts\n// Auto-generated src/models.ts\nexport interface Todo {\n  _id: string;\n  content: string;\n  done?: boolean | undefined | null;\n}\n\nexport type Models = {\n  ['AuthorizedUserMutation']: {\n    createTodo: {\n      args: {\n        content: string;\n        secret?: Secret | undefined | null;\n      };\n    };\n  };\n};\n```\n\nWrite resolvers with full type inference:\n\n```ts\n// src/todos/resolvers/AuthorizedUserMutation/createTodo.ts\nimport { createResolvers } from '../../axolotl.js';\n\nexport default createResolvers({\n  AuthorizedUserMutation: {\n    createTodo: async ([source], { content }) =\u003e {\n      // TypeScript knows `content` is string\n      // TypeScript knows this must return string\n      const _id = Math.random().toString(8);\n      db.todos.push({ owner: src._id, content, _id });\n      return _id;\n    },\n  },\n});\n```\n\nReturn a number instead of a string and TypeScript complains immediately.\n\n## Micro-Federation\n\nThe example splits schemas by domain:\n\n```ts\nsrc/\n├── todos/\n│   ├── schema.graphql\n│   └── resolvers/\n├── users/\n│   ├── schema.graphql\n│   └── resolvers/\n└── resolvers.ts\n```\n\nAxolotl merges them:\n\n```ts\n// src/resolvers.ts\nimport { mergeAxolotls } from '@aexol/axolotl-core';\nimport todosResolvers from '@/src/todos/resolvers/resolvers.js';\nimport usersResolvers from '@/src/users/resolvers/resolvers.js';\n\nexport default mergeAxolotls(todosResolvers, usersResolvers);\n```\n\nTypes flow through the merge.\n\n## Frontend with Zeus\n\nZeus generates a typed GraphQL client from the schema:\n\n```ts\n// frontend/src/api.ts\nimport { Chain } from '../../src/zeus/index';\n\nexport const createGqlClient = (token?: string) =\u003e {\n  const headers: Record\u003cstring, string\u003e = {\n    'Content-Type': 'application/json',\n  };\n  if (token) {\n    headers['token'] = token;\n  }\n  return Chain('/graphql', { headers });\n};\n```\n\nQueries are type-safe:\n\n```ts\n// frontend/src/hooks/useTodos.ts\nconst fetchTodos = async () =\u003e {\n  const data = await gql()('query')({\n    user: {\n      todos: { _id: true, content: true, done: true },\n    },\n  });\n\n  // TypeScript knows data.user?.todos is Todo[]\n  if (data.user?.todos) {\n    setTodos(data.user.todos);\n  }\n};\n```\n\nMutations too:\n\n```ts\nconst createTodo = async (content: string) =\u003e {\n  await gql()('mutation')({\n    user: {\n      createTodo: [{ content }, true],\n    },\n  });\n};\n```\n\nThe `[{ content }, true]` syntax means: pass these arguments, return this field. Type
214Script validates that `content` matches the schema.\n\n## Express + Vite on One Server\n\nThe whole stack runs on one Express server:\n\n```ts\n// src/index.ts\nasync function startServer() {\n  const app = express();\n\n  // Mount GraphQL\n  const { yoga } = adapter({ resolvers, directives });\n  app.use('/graphql', yoga);\n\n  // Development: Vite middleware for HMR\n  if (!isProduction) {\n    const vite = await createViteServer({\n      server: { middlewareMode: true },\n      appType: 'custom',\n    });\n    app.use(vite.middlewares);\n  } else {\n    // Production: serve built assets\n    app.use(sirv(resolve(__dirname, '../dist/client')));\n  }\n\n  // SSR for all other routes\n  app.use('*all', async (req, res) =\u003e {\n    const { html } = await render(req.originalUrl);\n    res.send(html);\n  });\n}\n```\n\nYou get:\n\n* HMR in development\n* SSR for SEO\n* One deployment artifact\n* No proxy config\n\n## The Type Flow\n\nA todo travels through the system like this:\n\n1. **Schema** defines `createTodo(content: String!): String!`\n2. **Axolotl** generates `args: { content: string }` for resolvers\n3. **Resolver** uses `{ content }` with TypeScript support\n4. **Zeus** generates client types from the same schema\n5. **React hook** calls `createTodo: [{ content }, true]` with type checking\n6. **Response** comes back typed\n\nChange the schema, run `axolotl build`, and TypeScript shows you what broke.\n\n## Try It\n\n```ts\ncd examples/yoga-federated\nnpm install\nnpm run dev\n```\n\nOpen http://localhost:4002:\n\n![](https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/media/screenshot-login-1765204379116.png)\n\nRegister and you're in and can create todos\n\n![](https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/media/screenshot-todo-created-1765204389217.png)\n\nGraphQL Playground at http://localhost:4002/graphql:\n\n![](https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/media/screenshot-playground-1765204385463.png)\n\n## What I Like About This\n\nAfter using this pattern, a few things stand out:\n\n1. **Schema changes propagate everywhere** - modify a field, run build, TypeScript tells you what broke on both backend and frontend\n2. **AI assistants actually help** - the `@resolver` directive means Copilot knows what to implement without explaining the architecture\n3. **One `npm run dev`** - no separate terminal for frontend, no proxy config, no CORS debugging\n4. **SSR just works** - good for SEO if you need it\n\nThe tradeoff is coupling - frontend and backend deploy together. For most projects that's fine. If you need independent scaling, split them later.\n\n## Links\n\n* [Axolotl Documentation](https://axolotl.aexol.com)\n* [GraphQL Zeus Documentation](https://zeus.aexol.com)\n* [Example Source Code](https://github.com/aexol-studio/axolotl/tree/main/examples/yoga-federated)\n\n***\n\n\n*Built with Axolotl + GraphQL Yoga + Zeus by* [Aexol Studio](https://aexol.com)","createdAt":1765204305529,"updatedAt":1784371494390,"image":{"url":"https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/blogpost/generated-image-november-29-2025-1-42-pm-1765205203487.jpeg","thumbnail":null,"alt":null},"author":{"name":"Artur Czemiel","position":" CEO","description":"I can help you create graph sourced source of the truth-based architecture of the existing app or plan a new one.","contact":"[email protected]","locale":null,"slug":"artur","_id":"672b79fdb87c7e889b9de818","createdAt":1730902525000,"updatedAt":1730902525000,"draft_version":null,"json_ld":null,"image":{"url":"https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/author/newavatar-copy-1730903534365.jpg","thumbnail":"https://aexol-cms.fra1.cdn.digitaloceanspaces.com/aexolcom/author/__thumbnails__/newavatar-copy-1730903534365.jpg","alt":"Artur Czemiel"}},"seo":{"page_title":"Full-Stack GraphQL Type Safety: Axolotl, Zeus \u0026 Vite Guide","meta_description":"Achieve full-stack type safety with Axolotl, Zeus, and Vite. Learn to secure your GraphQL APIs and React apps with TypeScript from schema to UI.","canonical":"https://aexol.com/posts/full-stack-graphql/","locale":"en","slug":"full-stack-graphql","_id":"6a5b58f14e048562808e9f04","createdAt":1784371441125,"updatedAt":1784371448222,"draft_version":false,"json_ld":null}},"navData":{"locale":"en","slug":"navigation","_id":"67a0a08fb22b10c4d4b813f7","createdAt":1738580111852,"updatedAt":1784446387035,"draft_version":false,"json_ld":null,"components":{"navbar":{"links":[{"text":"Our work","href":"/#","
214is_button":null,"foreground_color":null,"background_color":null,"component":{"title":"Case studies","description":"See how our AI-native approach has helped organizations transform their software development.","link_text":"","link_url":"","background_color":"#0f172a","sublinks":[{"title":"SportXpert","description":"AI-powered analytics platform for football betting analysis.","href":"/casestudies/sportxpert/"},{"title":"Deliverky","description":"Feature-rich last-mile delivery platform for HoReCa and courier companies.","href":"/casestudies/deliverky/"},{"title":"Exalted","description":"E-commerce MVP for premium Czech sportswear brand.","href":"/casestudies/exalted/"},{"title":"Samarite","description":"Content management tool for leading Polish cosmetics brand.","href":"/casestudies/samarite/"},{"title":"Magiczny Rynek","description":"Modern online store with TCG games and accessories.","href":"/casestudies/magicznyrynek/"}],"columns":[]}},{"text":"Services","href":"/#","is_button":null,"foreground_color":null,"background_color":null,"component":{"title":"What we build","description":"From MVP to enterprise — web apps, mobile apps and SaaS with AI-native methodologies.","link_text":"","link_url":"","background_color":"#0f172a","sublinks":[{"title":"Web Apps","description":"Modern, high-performance web applications with full backend.","href":"/services/web-development/"},{"title":"Mobile Apps","description":"Native and cross-platform mobile apps for iOS and Android.","href":"/services/mobile-development/"},{"title":"MVP Development","description":"Fast idea validation — from concept to working prototype.","href":"/services/mvp-development/"},{"title":"AI \u0026 Automation","description":"Integrate AI into your existing systems and workflows.","href":"/services/ai-services/"}],"columns":[]}},{"text":"Pricing","href":"/pricing/","is_button":null,"foreground_color":null,"background_color":null,"component":{"title":null,"description":null,"link_text":null,"link_url":null,"background_color":null,"sublinks":[],"columns":[]}},{"text":"Industries","href":"/#","is_button":null,"foreground_color":null,"background_color":null,"component":{"title":"Organizations We Serve","description":"Enterprises, software companies, and scale-ups.","link_text":null,"link_url":null,"background_color":"#0f172a","sublinks":[{"title":"E-commerce","description":"Online stores and marketplaces optimized for sales.","href":"/industries/ecommerce/"},{"title":"SaaS","description":"Launch your SaaS faster with AI-native development.","href":"/industries/saas/"},{"title":"GovTech","description":"Digital government services, citizen portals, e-administration.","href":"/industries/govtech/"},{"title":"Influencer Apps","description":"Mobile apps that grow influencer communities and monetization.","href":"/industries/influencer-apps/"},{"title":"B2B Apps","description":"Enterprise process planning, workflow automation, ERP/CRM integrations.","href":"/industries/b2b-apps/"}],"columns":[]}},{"text":"Technologies","href":"/#","is_button":null,"foreground_color":null,"background_color":null,"component":{"title":"AEXOL™ Stack","description":"Proprietary platform for AI-native software development.","link_text":"","link_url":"","background_color":"#0f172a","sublinks":[],"columns":[{"title":"AEXOL™ Stack","sublinks":[{"text":"SDL","url":"/technologies/sdl/"},{"text":"Studio","url":"/technologies/studio/"},{"text":"Spectral","url":"/technologies/spectral/"}]}]}},{"text":"Resources Hub","href":"/resources-hub/","is_button":null,"foreground_color":null,"background_color":null,"component":{"title":null,"description":null,"link_text":null,"link_url":null,"background_color":null,"sublinks":[],"columns":[]}},{"text":"Contact us","href":"/contact/","is_button":true,"foreground_color":"#ffffff","background_color":"#3b82f6","component":{"title":null,"description":null,"link_text":null,"link_url":null,"background_color":null,"sublinks":[],"columns":[]}}]},"footer":{"address":{"title":"Aexol Sp. z o.o.","address_lines":["Mławska 4/U7","15-411 Białystok","Poland, EU","KRS: 0000602817","REGON: 363749060","VAT ID: PL5423253283"]},"contact":{"title":"Contact","contact_points":["[email protected]","PL/EN: +48 887 723 965","+48 668 049 888","PL/FR: +48 530 760 594"]},"columns":[{"title":"Services","main_link":"","links":[{"text":"Web Apps","url":"/services/web-development/"},{"text":"Mobile Apps","url":"/services/mobile-development/"},{"text":"MVP Development","url":"/services/mvp-development/"},{"text":"AI \u0026 Automation","url":"/services/ai-services/"},{"text":"Pricing","url":"/pricing/"}]},{"title":"AEXOL™ Stack","main_link":"","links":[{"text":"SDL","url":"/technologies/sdl/"},{"text":"Studio","url":"/technologies/studio/"},{"text":"Spectral","url":"/technologies/spectral/"}
214]},{"title":"Industries","main_link":"","links":[{"text":"E-commerce","url":"/industries/ecommerce/"},{"text":"SaaS","url":"/industries/saas/"},{"text":"GovTech","url":"/industries/govtech/"},{"text":"Influencer Apps","url":"/industries/influencer-apps/"},{"text":"B2B Apps","url":"/industries/b2b-apps/"}]},{"title":"Resources","main_link":"","links":[{"text":"Articles","url":"/resources-hub/?tab=articles"},{"text":"Products","url":"/resources-hub/?tab=products"},{"text":"Open-source","url":"/resources-hub/?tab=open_source"},{"text":"E-Books","url":"/resources-hub/?tab=ebooks"}]}]}}},"typographyData":{"glass_bg":null,"glass_blur":null,"badge_bg":null,"badge_text":null,"badge_border":null,"ai_grad_1":null,"ai_grad_2":null,"ai_grad_3":null,"card_radius":null,"section_padding":null,"locale":null,"slug":"blue","_id":"67b49efd9f3af4f3038791eb","createdAt":1739890429802,"updatedAt":1746954165273,"draft_version":false,"json_ld":null,"fonts":{"text_primary_color":"#0a0a0a","text_secondary_color":"#3a3c40","text_tertiary_color":"#fff","text_accent_color":"#4816de"},"buttons":{"foreground_color":"#4816de","background_color":"#0a0a0a","text_color":"#fff"},"components":{"primary_background_color":"#4816de","secondary_background_color":"#fff"}},"cta":{"span":"Ready to start?","title":"Let's talk about your project.","desc":"Free consultation and quote within 48h. No strings attached.","button_text":"Contact us","button_url":"/contact","background_color":"#eff6ff","locale":"en","slug":"cta","_id":"679bdba6e8d7232cd32f5fb3","createdAt":1738267558225,"updatedAt":1784296474942,"draft_version":false,"json_ld":null},"alternates":[{"locale":"pl","components":{"seo":{"canonical":"https://aexol.com/pl/posts/full-stack-graphql/"}}},{"locale":"en","components":{"seo":{"canonical":"https://aexol.com/posts/full-stack-graphql/"}}}]},"__N_SSP":true},"page":"/posts/[slug]","query":{"slug":"full-stack-graphql"},"buildId":"zmgWC04bnd70evER7bsVb","isFallback":false,"isExperimentalCompile":false,"gssp":true,"locale":"en","locales":["en","pl"],"defaultLocale":"en","scriptLoader":[]}</script>
214<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"e59b7725c74c49daba54dc8fd84aac26","r":1,"spa":2}' crossorigin="anonymous"></script>
214
215</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.