<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Andreas Bergström</title>
    <description>The latest articles on Forem by Andreas Bergström (@andreasbergstrom).</description>
    <link>https://forem.com/andreasbergstrom</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F153469%2F5c1970f5-0d22-46e9-af0c-6931bb91d856.jpg</url>
      <title>Forem: Andreas Bergström</title>
      <link>https://forem.com/andreasbergstrom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/andreasbergstrom"/>
    <language>en</language>
    <item>
      <title>Using FastMCP with OpenAI and Avoiding Session Termination Issues</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Sun, 10 Aug 2025 10:32:13 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/using-fastmcp-with-openai-and-avoiding-session-termination-issues-k3h</link>
      <guid>https://forem.com/andreasbergstrom/using-fastmcp-with-openai-and-avoiding-session-termination-issues-k3h</guid>
      <description>&lt;p&gt;If you're plugging a FastMCP server into OpenAI's Responses API and your sessions keep dying with &lt;code&gt;Session has been terminated&lt;/code&gt;, the fix is one flag: &lt;code&gt;stateless_http=True&lt;/code&gt; when you instantiate &lt;code&gt;FastMCP(...)&lt;/code&gt;. OpenAI sends a &lt;code&gt;DELETE&lt;/code&gt; after each call without recreating the session, so anything stateful gets terminated between requests.&lt;/p&gt;

&lt;p&gt;The full post covers the JSON-RPC error you'll actually see, the minimal server change to make it work, and the caveats — session state and certain bi-directional streaming patterns drop out in stateless mode. Worth a quick read if you're hitting the same one-call-then-broken behaviour.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/fastmcp-openai-session-termination" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>fastmcp</category>
      <category>openai</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Redirecting mobile users to App or Play Store in NextJS</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Mon, 27 Nov 2023 19:53:11 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/redirecting-mobile-users-to-app-or-play-store-using-nextjs-3pp1</link>
      <guid>https://forem.com/andreasbergstrom/redirecting-mobile-users-to-app-or-play-store-using-nextjs-3pp1</guid>
      <description>&lt;p&gt;If you're promoting a mobile app for both iOS and Android and want a single URL or QR code that drops users into the correct store, you don't need a 3rd-party redirect service. A NextJS middleware that matches &lt;code&gt;userAgent&lt;/code&gt; against &lt;code&gt;iP(hone|ad|od)&lt;/code&gt; and &lt;code&gt;Android&lt;/code&gt; regexes does it in ~15 lines, runs before any render, and keeps the contact point — and any SEO it earns — on your own domain.&lt;/p&gt;

&lt;p&gt;The full post walks through the &lt;code&gt;middleware.ts&lt;/code&gt; plus the placeholder &lt;code&gt;app/get.tsx&lt;/code&gt; page that triggers it, with notes on the iOS-vs-Android UX quirk and why owning that redirect matters once QR codes are out in the wild and outlive your vendor relationships.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/nextjs-mobile-app-store-redirect" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>mobile</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Python del vs assigning to None</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Sat, 11 Nov 2023 16:37:38 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/python-del-vs-assigning-to-none-5387</link>
      <guid>https://forem.com/andreasbergstrom/python-del-vs-assigning-to-none-5387</guid>
      <description>&lt;p&gt;Both &lt;code&gt;x = None&lt;/code&gt; and &lt;code&gt;del x&lt;/code&gt; look like ways to release a variable in Python, but they aren't equivalent. &lt;code&gt;x = None&lt;/code&gt; keeps the name bound and just rebinds it to &lt;code&gt;NoneType&lt;/code&gt; (still ~16 bytes); &lt;code&gt;del x&lt;/code&gt; removes the binding entirely so the name itself is gone. Touch &lt;code&gt;x&lt;/code&gt; after &lt;code&gt;del&lt;/code&gt; and you get a &lt;code&gt;NameError&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The full post walks through a worked example with &lt;code&gt;sys.getsizeof&lt;/code&gt; and &lt;code&gt;gc.collect()&lt;/code&gt; showing the byte difference, then disassembles both versions with &lt;code&gt;dis.dis&lt;/code&gt; so you can see &lt;code&gt;del&lt;/code&gt; compiles to a single &lt;code&gt;DELETE_FAST&lt;/code&gt; while assigning to &lt;code&gt;None&lt;/code&gt; becomes a &lt;code&gt;LOAD_CONST&lt;/code&gt; + &lt;code&gt;STORE_FAST&lt;/code&gt; pair.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/python-del-vs-none" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>performance</category>
    </item>
    <item>
      <title>Node 21 brings built-in WebSocket support</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Mon, 16 Oct 2023 18:19:32 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/node-21-might-have-websockets-built-in-24f3</link>
      <guid>https://forem.com/andreasbergstrom/node-21-might-have-websockets-built-in-24f3</guid>
      <description>&lt;p&gt;Node 21 finally ships with a built-in WebSocket client — no more pulling in &lt;code&gt;ws&lt;/code&gt; or &lt;code&gt;socket.io-client&lt;/code&gt; for a basic browser-style API on the server side. Deno and Bun have shipped this for a while; this closes the gap.&lt;/p&gt;

&lt;p&gt;The full post (written just ahead of the v21 release) tracks the upstream Undici PR and the long-running Node issue thread that pushed it across the finish line, with a link to the v21 release announcement once it landed.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/node-21-built-in-websocket" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
    </item>
    <item>
      <title>Configure TypeORM migrations in 5 minutes</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Sun, 15 Oct 2023 08:39:24 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/configure-typeorm-migrations-in-5-minutes-2njg</link>
      <guid>https://forem.com/andreasbergstrom/configure-typeorm-migrations-in-5-minutes-2njg</guid>
      <description>&lt;p&gt;Setting up TypeORM migrations in a NestJS project is fiddly across two configs and four npm scripts the first time you do it, but mechanical once you know the shape. Wire &lt;code&gt;migrationsRun: true&lt;/code&gt; into &lt;code&gt;TypeOrmModule.forRootAsync&lt;/code&gt;, add a separate &lt;code&gt;typeorm.config.ts&lt;/code&gt; &lt;code&gt;DataSource&lt;/code&gt; for the CLI to import, and four package.json scripts cover run/generate/create/revert.&lt;/p&gt;

&lt;p&gt;The full post has the exact &lt;code&gt;app.module.ts&lt;/code&gt;, &lt;code&gt;typeorm.config.ts&lt;/code&gt;, and &lt;code&gt;package.json&lt;/code&gt; snippets to copy, plus notes on why &lt;code&gt;synchronize&lt;/code&gt; should never be true in production and how &lt;code&gt;generate-migration&lt;/code&gt; diffs your entities against the live schema to write the SQL for you.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/typeorm-migrations-nestjs" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>typeorm</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Easily style active links in Tanstack Router</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Sat, 14 Oct 2023 07:45:23 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/easily-style-active-links-in-tanstack-router-7n</link>
      <guid>https://forem.com/andreasbergstrom/easily-style-active-links-in-tanstack-router-7n</guid>
      <description>&lt;p&gt;TanStack Router's &lt;code&gt;Link&lt;/code&gt; accepts an &lt;code&gt;activeProps&lt;/code&gt; prop that gets spread onto the rendered element only when the link matches the current route — including &lt;code&gt;className&lt;/code&gt;. So styling the active item in a navbar is just &lt;code&gt;&amp;lt;Link activeProps={{ className: 'text-black' }}&amp;gt;&lt;/code&gt; — no &lt;code&gt;useMatches&lt;/code&gt;, no manual &lt;code&gt;pathname&lt;/code&gt; comparison.&lt;/p&gt;

&lt;p&gt;The full post has a short &lt;code&gt;MainNav&lt;/code&gt; example mapping menu items to &lt;code&gt;Link&lt;/code&gt;s plus a pointer to TanStack's docs for the rest of the active-state knobs.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/tanstack-router-active-link-styles" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
      <category>ux</category>
    </item>
    <item>
      <title>Finally you can skip dotenv in Node</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Sat, 09 Sep 2023 07:33:31 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/finally-you-can-skip-dotenv-in-node-14ml</link>
      <guid>https://forem.com/andreasbergstrom/finally-you-can-skip-dotenv-in-node-14ml</guid>
      <description>&lt;p&gt;Node 20.6 added built-in &lt;code&gt;.env&lt;/code&gt; file loading, so &lt;code&gt;node --env-file=.env index.js&lt;/code&gt; does what &lt;code&gt;dotenv&lt;/code&gt; used to. It also picks up &lt;code&gt;NODE_OPTIONS&lt;/code&gt; from the same file — convenient when you want flags like &lt;code&gt;--experimental-modules&lt;/code&gt; colocated with the rest of your runtime config rather than scattered between &lt;code&gt;package.json&lt;/code&gt; and shell.&lt;/p&gt;

&lt;p&gt;The full post covers the syntax, why this still doesn't help React or React Native (those don't run on the Node runtime in prod), and where Vite/Astro projects already had a similar story for their own dev servers.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/node-built-in-env-file-no-dotenv" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>npm</category>
    </item>
    <item>
      <title>How to style for print in Tailwind</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Sun, 13 Aug 2023 18:21:07 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/how-to-easily-use-media-queries-for-print-in-tailwind-2o9a</link>
      <guid>https://forem.com/andreasbergstrom/how-to-easily-use-media-queries-for-print-in-tailwind-2o9a</guid>
      <description>&lt;p&gt;Tailwind doesn't expose &lt;code&gt;print:&lt;/code&gt; and &lt;code&gt;screen:&lt;/code&gt; modifiers by default, but extending &lt;code&gt;theme.screens&lt;/code&gt; in &lt;code&gt;tailwind.config.js&lt;/code&gt; with &lt;code&gt;print: { raw: 'print' }&lt;/code&gt; and &lt;code&gt;screen: { raw: 'screen' }&lt;/code&gt; opens them up — no plugin needed. Then &lt;code&gt;print:hidden&lt;/code&gt; on the navbar, &lt;code&gt;print:text-xl&lt;/code&gt; for paper-friendly typography, and &lt;code&gt;print:block&lt;/code&gt; toggles for swapping to a grayscale image just work.&lt;/p&gt;

&lt;p&gt;The full post covers the config tweak, the handful of classes that matter most for print (hide chrome, swap images, surface link URLs via a tiny CSS rule), and why it's worth caring at all for document-oriented sites.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/tailwind-print-styles" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>webdev</category>
      <category>css</category>
    </item>
    <item>
      <title>Understanding Cache-Control and ETag for efficient web caching</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Thu, 10 Aug 2023 07:49:17 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/understanding-cache-control-and-etag-for-efficient-web-caching-2nf5</link>
      <guid>https://forem.com/andreasbergstrom/understanding-cache-control-and-etag-for-efficient-web-caching-2nf5</guid>
      <description>&lt;p&gt;&lt;code&gt;Cache-Control&lt;/code&gt; and &lt;code&gt;ETag&lt;/code&gt; solve different halves of the same problem and are at their best together: &lt;code&gt;Cache-Control&lt;/code&gt; says how long the client can skip the server entirely (&lt;code&gt;max-age&lt;/code&gt;, &lt;code&gt;no-cache&lt;/code&gt;, &lt;code&gt;public&lt;/code&gt;/&lt;code&gt;private&lt;/code&gt;, &lt;code&gt;must-revalidate&lt;/code&gt;); &lt;code&gt;ETag&lt;/code&gt; is the freshness check used when the cache does want to ask — the client sends &lt;code&gt;If-None-Match&lt;/code&gt;, the server replies &lt;code&gt;304 Not Modified&lt;/code&gt; if the tag matches and saves the bytes.&lt;/p&gt;

&lt;p&gt;The full post walks through the directives, what &lt;code&gt;If-None-Match&lt;/code&gt; looks like on the wire, and why &lt;code&gt;ETag&lt;/code&gt;-only is worse than the pair (more round trips, no public/private split, no &lt;code&gt;immutable&lt;/code&gt; on versioned assets).&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/http-cache-control-etag" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>http</category>
      <category>webdev</category>
      <category>webperf</category>
      <category>caching</category>
    </item>
    <item>
      <title>Simplify TypeScript builds with esbuild and skip tsc/tsx</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Wed, 09 Aug 2023 07:49:22 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/simplify-typescript-builds-with-esbuild-and-skip-tsctsx-2124</link>
      <guid>https://forem.com/andreasbergstrom/simplify-typescript-builds-with-esbuild-and-skip-tsctsx-2124</guid>
      <description>&lt;p&gt;If &lt;code&gt;tsc&lt;/code&gt; (or &lt;code&gt;tsx&lt;/code&gt; in dev) is the slow step in your TypeScript build, esbuild can replace both. A single npm script — &lt;code&gt;esbuild $(find src -name '*.ts') --platform=node --target=esnext --outdir=build --format=cjs&lt;/code&gt; — does the same job in a fraction of the time, and &lt;code&gt;--watch&lt;/code&gt; makes it usable as the dev compiler too.&lt;/p&gt;

&lt;p&gt;The full post breaks down each esbuild flag (&lt;code&gt;--platform&lt;/code&gt;, &lt;code&gt;--target&lt;/code&gt;, &lt;code&gt;--format&lt;/code&gt;, &lt;code&gt;--outdir&lt;/code&gt;, &lt;code&gt;--watch&lt;/code&gt;), shows the &lt;code&gt;package.json&lt;/code&gt; scripts for build/dev/watch, and pairs it with &lt;code&gt;concurrently&lt;/code&gt; for a single dev-server command.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/esbuild-typescript-skip-tsc" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>package.json: Not just a file, but a Developer's Toolkit</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Tue, 08 Aug 2023 05:51:17 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/packagejson-not-just-a-file-but-a-developers-toolkit-2666</link>
      <guid>https://forem.com/andreasbergstrom/packagejson-not-just-a-file-but-a-developers-toolkit-2666</guid>
      <description>&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt; is more than a manifest — npm &lt;code&gt;scripts&lt;/code&gt; is a small task runner with hooks, env-var injection, lifecycle stages, and parallel execution baked in. &lt;code&gt;pre&lt;/code&gt;/&lt;code&gt;post&lt;/code&gt; prefixes auto-bracket a task with setup/teardown; &lt;code&gt;process.env.npm_package_*&lt;/code&gt; lets scripts read their own metadata; &lt;code&gt;concurrently npm:start:*&lt;/code&gt; fans out a handful of related scripts in one command.&lt;/p&gt;

&lt;p&gt;The full post collects the patterns worth knowing — pre/post hooks, env vars, &lt;code&gt;cross-env&lt;/code&gt;, &lt;code&gt;concurrently&lt;/code&gt;/&lt;code&gt;npm-run-all&lt;/code&gt;, lifecycle scripts like &lt;code&gt;prepublish&lt;/code&gt;, command-line argument forwarding via &lt;code&gt;--&lt;/code&gt;, and when &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;/&lt;code&gt;&amp;amp;&lt;/code&gt; is fine vs when you actually want a task runner.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/package-json-npm-scripts-toolkit" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>npm</category>
    </item>
    <item>
      <title>The future of AI assistants might begin in your app settings</title>
      <dc:creator>Andreas Bergström</dc:creator>
      <pubDate>Mon, 07 Aug 2023 12:28:22 +0000</pubDate>
      <link>https://forem.com/andreasbergstrom/the-future-of-ai-assistants-revolutionizing-app-settings-using-large-language-models-382e</link>
      <guid>https://forem.com/andreasbergstrom/the-future-of-ai-assistants-revolutionizing-app-settings-using-large-language-models-382e</guid>
      <description>&lt;p&gt;App settings menus have grown into the Yellow Pages of software — a maze of toggles and sliders nobody actually wants to navigate. LLM-backed assistants suggest a way out: instead of digging for the dark-mode toggle, you tell the assistant "dark theme, no notifications during work, max privacy" and it walks the settings on your behalf.&lt;/p&gt;

&lt;p&gt;The full post argues this is the next CLI-to-GUI-style shift — settings as conversation rather than form — and what app developers and AI researchers need to get right (privacy, bias, reliability) for that transition not to fall on its face.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://andreasbergstrom.dev/posts/ai-assistants-app-settings" rel="noopener noreferrer"&gt;andreasbergstrom.dev&lt;/a&gt; — read the full post there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>llm</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>chatgpt</category>
    </item>
  </channel>
</rss>
