<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged devex</title>
<link>https://coderlegion.com/tag/devex</link>
<description>Powered by Question2Answer</description>
<item>
<title>What even is a developer experience audit?</title>
<link>https://coderlegion.com/32861/what-even-is-a-developer-experience-audit</link>
<description>&lt;p&gt;Since getting into the Developer Relations space, I take onboarding to new companies as an opportunity to evaluate what the overall product experience is like. This comes with all sorts of fun things like identifying broken links to fully broken internal processes. And everything in between&lt;/p&gt;
&lt;p&gt;I am a strong believer that everyone is doing their best. I am also rational in understanding that priorities and focus change regularly. I want to make sure I approach this with curiosity and enthusiasm to propose a solution and fix it myself, if that's possible. After all, I probably have less meetings and less responsibilities than everyone else, simply by being &lt;em&gt;new&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;If I can't fix it myself, I propose a recommendation. A former manager of mine would be thrilled to see me bringing solutions, not problems. (To be fair to both of us, the platform I supported at the time didn't have a lot of solutions but certainly had a lot of problems.)&lt;/p&gt;
&lt;p&gt;So with a use case in hand, I set off to see what the developer experience was like for Apryse. &lt;/p&gt;
&lt;h3 id=&quot;but-wait-where-does-developer-experience-fit-in-developer-relations-&quot;&gt;But wait, where does Developer Experience fit in Developer Relations?&lt;/h3&gt;
&lt;p&gt;Before we get into the audit details, let's address the DevEx vs. the DevRel elephant in the room. &lt;/p&gt;
&lt;p&gt;For me, Developer Relations is the broader umbrella that encompasses awareness (advocacy), enablement (developer experience), and engagement (community).&lt;/p&gt;
&lt;p&gt;Some companies will bucket this a little different, including the one I'm at now, where Developer Experience is the umbrella but the core focus areas are still largely covered. At Arpyse, we also include AEO under Developer Experience which I think fits nicely in this era of AI-enabled or AI-assisted builders.&lt;/p&gt;
&lt;p&gt;Now let's talk about audit process in terms of awareness, enablement, and engagement. &lt;/p&gt;
&lt;h3 id=&quot;the-process&quot;&gt;The process&lt;/h3&gt;
&lt;p&gt;I want to try to replicate, to the best of my ability, what the &lt;strong&gt;public facing&lt;/strong&gt; developer experience is like. How do developers find the product, how can they try it out, and then how can they (or someone else in the company) start the purchasing and procurement process.&lt;/p&gt;
&lt;p&gt;Doing this during onboarding should be the easiest time to ever do this because you probably have little to no deep product knowledge. you can literally approach it like an external developer because you are one. Unless your onboarding includes product training, which is cheating if it's only available to internals.&lt;/p&gt;
&lt;h4 id=&quot;discovery-awareness-&quot;&gt;Discovery (awareness)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Can I find the product when I'm looking for it? Is it positioned well against competitors?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In today's world, discovery includes both a traditional search and AI tools, including LLMs like Claude, but also includes AI search summaries, like the ones you see at the top of an otherwise traditional Google search. &lt;/p&gt;
&lt;p&gt;I approach this like any research project I did in school - lots of keywords, questions, and use case based researching. Then I see what kind of results I get.&lt;/p&gt;
&lt;p&gt;If you think only your marketing website or your docs are your entry points for a developer audience, you have some work to do.&lt;/p&gt;
&lt;p&gt;Consider other entry points, like if your product is available on a cloud or platform marketplace, as developers participating in that ecosystem may start there first - think a Salesforce or Appian developer starting in their marketplace rather than accidentally finding something not in the marketplace already and having to build it full custom. Is this information up-to-date? Well maintained and linked back to more granular information across your website and docs? Does it show up on the marketplace search with vague terms or only the company or product name? &lt;/p&gt;
&lt;p&gt;Beyond marketplaces think of entry points like GitHub, package managers, or other places libraries and dependencies already live. Unless I'm starting from scratch or doing a re-platforming effort, the closer you are to where I'm already working, the easier it will be for me to pick it up. And here again, is this information up-to-date, well maintained, and linked back to more granular information? It's not enough to just be listed, it needs to look safe and maintained, often with very limited context.&lt;/p&gt;
&lt;p&gt;Outside the scope of this audit, you can also evaluate broad, general awareness activities typically managed by marketing like events, webinars, blogs, etc. If I go to a developer conference, is Apryse there and how quickly can I understand what the product does in a conference setting?&lt;/p&gt;
&lt;p&gt;All of this is part of the discovery process.&lt;/p&gt;
&lt;p&gt;One thing I should mention before moving on - if your product &lt;em&gt;doesn't&lt;/em&gt; come up when and where you expect it, that's a notable gap. Congrats, you have action items following your audit. To me, awareness gaps are the most critical to address immediately because if people (and AI) can't find you, they can't use you. Fix that!&lt;/p&gt;
&lt;h4 id=&quot;evaluation-amp-trial-enablement-&quot;&gt;Evaluation &amp;amp; trial (enablement)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;I found the product I think I want to use, but I need to check on the features and eventually build a proof of concept (PoC).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You've been found, either by humans or AI, and they are moving forward with understanding and using your product, often in some kind of trial capacity. &lt;/p&gt;
&lt;p&gt;Before they start building, they need to know if your features and capabilities will solve their problems. Maybe they've seen some marketing pages or blog describing this, but this is where they will start digging for more details.&lt;/p&gt;
&lt;p&gt;This is probably where my process has changed the most in recent years. Using AI tools I can go from discovery to building really fast, sometimes even in the same chat.&lt;/p&gt;
&lt;p&gt;And I did, with several LLMs on basic or free tiers with as little access to memories or prior knowledge as I could possibly give them. I didn't want them to taint my results by knowing I worked for Apryse because I wanted to experience what an external developer would experience, and a bias to Apryse because I was an employee was going to harm that.&lt;/p&gt;
&lt;p&gt;During this evaluation phase is also where I check competitors and even PoC them too. You want to be choosy about this step because it's either time consuming or compute intensive (tokens), but it's a very realistic step for developers evaluating multiple options. &lt;/p&gt;
&lt;p&gt;I'm evaluating the features, the ease of implementation, the clarity of documentation or other assets available for reference, and ultimately how much debugging did I have to do to stand up a working PoC. If this goes smoothly, I will literally go tell all my tech friends about it. (And this should be your goal, to have people outside the company talking about how great it is.)&lt;/p&gt;
&lt;h5 id=&quot;trial-keys-licenses-and-more&quot;&gt;Trial keys, licenses, and more&lt;/h5&gt;
&lt;p&gt;If your product has a trial process, it should be as frictionless as possible. I get that you want leads. You know what I, as an external developer, want? To figure out how many PoCs I have to do before I recommend a solution to my manager on a tight timeline. And know that when I build a PoC, I've timed it so it still works when I have to do a demo.&lt;/p&gt;
&lt;p&gt;Your trial process should be super clear. How many days, weeks, credits, runs is the trial valid for? What features are included or not? Will I see uninformative error messages when using a trial key vs. a production key?&lt;/p&gt;
&lt;p&gt;It does not matter if the friction experienced in this phase is 100% because of how trial keys or licenses are implemented. You need to fix that. External developers shouldn't have to absorb that.&lt;/p&gt;
&lt;h5 id=&quot;a-curated-developer-journey&quot;&gt;A curated developer journey&lt;/h5&gt;
&lt;p&gt;This is the hill I'm willing to die on, sometimes daily. You cannot risk developers or AI defining their own developer journey. You need to own and nurture this. This stage of the audit is where this becomes alarmingly clear. &lt;/p&gt;
&lt;p&gt;Taking a use case, I usually pick a programming language or framework along with it. In this case, I went Javascript (React + Node, with some Vite and Angular sprinkled in along the way. Remember, I ended up doing like 5 or 6 PoCs across Apryse and competitors.) &lt;/p&gt;
&lt;p&gt;With both my own eyeballs and mouse pointer AND, separately, my crew of LLMs, I wanted to see if there was a clear, defined journey through Apryse for a Javascript developer. This was a well supported journey, but not necessarily a curated one depending on where I went or what questions I asked. For example, landing on the marketing website, we don't really link to a developer portal. In fact, we have about 4 pages I would consider someone external to Apryse calling a &quot;developer portal,&quot; so we'll need to fix that.&lt;/p&gt;
&lt;p&gt;A north star goal here would be for my various programming languages or frameworks, a developer in that space can move from discovery to building with clearly identified resources that we nurture, specific to their needs and use cases. For example, a Java developer would probably have different needs and use cases simply by living in the server space (Apryse Server SDK) compared to a developer using WebViewer (Web SDK). This could end up being the same developer, but they are solving different aspects of the problem and need an intro and understanding of our different SDKs. &lt;/p&gt;
&lt;h4 id=&quot;up-and-running-and-beyond-engagement-&quot;&gt;Up and running, and beyond (engagement)&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Is there anyone out there to support me? How can I get deeper knowledge?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Once I've successfully built a PoC, or like 5? 6...? in my case, I need to help whoever is actually going to do the purchasing make a final decision to make the purchase happen.&lt;/p&gt;
&lt;p&gt;And in parallel, I need to make sure I know how and where to get support, either paid or community. Ideally, this is open and searchable because I'm both lazy and antisocial. &lt;/p&gt;
&lt;p&gt;This is where I look for community support platforms, forums like Discourse, messaging platforms like Slack or Discord, GitHub communities, etc. I also evaluate their community health - is anyone actually posting? Are the only responses from employees or contributors? Does it look like a place I would feel safe asking a question?&lt;/p&gt;
&lt;p&gt;If there are hundreds or thousands of people silently hanging out, this is a red flag. If only employees or contributors are responding, this is probably a yellow flag or maybe even green if you were looking for free (community) support. As a community grows, the community support should scale with it. If it doesn't, this might be something to look in to.&lt;/p&gt;
&lt;p&gt;I also look at GitHub and forums outside of the direct control of the project or company. What's the sentiment here? Do issues remain open with no responses? Are PRs stale and neglected? Is there a whole subreddit bashing the project?&lt;/p&gt;
&lt;p&gt;At this point, I also start looking for any signs of a champions program or certified developers in this space. This might come up on LinkedIn or a community support forum. These are usually really healthy indicators, that someone external to the company cares enough to go the extra mile with the technology. They may speak at conferences and share their experience too, which loops back to the general awareness activities. &lt;/p&gt;
&lt;p&gt;With this information I can usually wrap up my recommendation and feel confident we are making a good choice.&lt;/p&gt;
&lt;h3 id=&quot;the-caveat&quot;&gt;The caveat&lt;/h3&gt;
&lt;p&gt;It's super important to stay as public and as focused on exactly what a given resource says. If you have access to internal experts or secret resources, this isn't a good replication of what an external user would have access to. If you overcome any and all friction with extensive research, that's not realistic with someone on a development team with a tight sprint timeline. &lt;/p&gt;
&lt;h3 id=&quot;the-ai-caveat&quot;&gt;The AI caveat&lt;/h3&gt;
&lt;p&gt;I took this particular audit as an opportunity to use every LLM and AI chatbot I could reasonably get my hands on - Claude, Microsoft Copilot, GitHub Copilot, Gemini, ChatGPT + Codex. Occasionally I would use them a bit adversarially quoting one to the other. I also wanted to see what kind of project structure they delivered, what kind of experience I had pair programming or debugging with them, and what kind of AI-enabled or assisted experience they delivered.&lt;/p&gt;
&lt;p&gt;Several times I had to reign them in because they could &lt;em&gt;see&lt;/em&gt; my email in my directory file tree or path and infer Apryse as my employer. I get that they are being &quot;smart&quot; but this is not what I wanted. Microsoft Copilot had broad internal access and I actually ended up abandoning it because it would go find internal resources after I would explicitly tell it to only look on the public internet.&lt;/p&gt;
&lt;p&gt;Speaking of public internet, GitHub Copilot out-of-the-box didn't have access to the public internet and neglected to share that with me. I wrote a whole &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/missamarakay/building-pocs-with-codex-and-github-copilot-while-they-try-to-adjust-my-poc-requirements-along-the-1fc9&quot;&gt;thing&lt;/a&gt; about that, but TL;DR it was GUESSING old npm versions before I was finally like CITE YOUR SOURCES and it couldn't... because it didn't have access to the internet. &lt;/p&gt;
&lt;h3 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h3&gt;
&lt;p&gt;So this was more info into my developer experience audit process. Have you done something similar? What does your process look like?&lt;/p&gt;
&lt;p&gt;Again, and I cannot stress this enough, this isn't a finger pointing exercise. Some things may be accidentally neglected or forgotten, just fix them or recommend a fix and move on. Some things may be missing because it just wasn't the right time to do them, and maybe it's still not the right time. &lt;/p&gt;
&lt;p&gt;The point is you now have a starting point for how and where to improve the developer experience, a great set of talking points to meet folks across the company and start building those cross-functional relationships, and you'll be able to directly impact the external developers trying to build a solution with your product. Lots of points. I think you get the point. 😉&lt;/p&gt;
&lt;p&gt;_Photo by &lt;a rel=&quot;nofollow&quot; href=&quot;https://unsplash.com/@olloweb?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot;&gt;Agence Olloweb&lt;/a&gt; on &lt;a rel=&quot;nofollow&quot; href=&quot;https://unsplash.com/photos/magnifying-glass-near-gray-laptop-computer-d9ILr-dbEdg?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot;&gt;Unsplash&lt;/a&gt;_&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/32861/what-even-is-a-developer-experience-audit</guid>
<pubDate>Wed, 28 Oct 2026 15:20:55 +0000</pubDate>
</item>
<item>
<title>The Backend Finally Makes Sense, Why I'm Loving Motia</title>
<link>https://coderlegion.com/25231/the-backend-finally-makes-sense-why-im-lovingmotia</link>
<description>&lt;p&gt;If you’ve ever pieced together a backend with Express routes, cron jobs, background workers, and a few AI agents duct taped together, you’ll know it works… but it’s not exactly pretty.&lt;/p&gt;
&lt;p&gt;You end up with code scattered across files and folders, logs in three different places, and brittle workflows that are hard to debug or extend.&lt;/p&gt;
&lt;p&gt;Recently, I came across &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.motia.dev/&quot;&gt;Motia&lt;/a&gt;, and it kind of blew my mind.&lt;/p&gt;
&lt;p&gt;It’s an open source backend framework that actually feels modern, and dare I say, &lt;strong&gt;fun&lt;/strong&gt; to use.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;what-is-motia-&quot;&gt;What is Motia?&lt;/h4&gt;
&lt;p&gt;Motia is a &lt;strong&gt;code first framework&lt;/strong&gt; that helps you build APIs, background jobs, scheduled tasks, and AI agents, all in a single project, with a shared runtime and clean visual feedback.&lt;/p&gt;
&lt;p&gt;It’s built with developers in mind and aims to make backend development feel as intuitive as frontend frameworks like NextJS.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;what-makes-motia-so-good-&quot;&gt;What Makes Motia So Good?&lt;/h4&gt;
&lt;p&gt; Everything is a “Step”&lt;/p&gt;
&lt;p&gt;In Motia, the basic unit is a &lt;strong&gt;Step&lt;/strong&gt;. It can be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An HTTP API endpoint&lt;/li&gt;
&lt;li&gt;A cron job&lt;/li&gt;
&lt;li&gt;A background task&lt;/li&gt;
&lt;li&gt;An AI agent&lt;/li&gt;
&lt;li&gt;An event handler&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each step is just a function, but Motia stitches them together into &lt;strong&gt;workflows&lt;/strong&gt; that you can visualize, monitor, and interact with in real time.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;-polyglot-support-yes-for-real-&quot;&gt;‍ Polyglot Support (Yes, for Real)&lt;/h4&gt;
&lt;p&gt;One of the coolest things about Motia: you’re not locked into one language. You can write steps in &lt;strong&gt;TypeScript&lt;/strong&gt;, and &lt;strong&gt;Python&lt;/strong&gt; (more coming soon), all in the same project.&lt;/p&gt;
&lt;p&gt;That means you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use Python for AI or data stuff&lt;/li&gt;
&lt;li&gt;Stick with JS/TS for APIs&lt;/li&gt;
&lt;li&gt;Experiment with Ruby if that’s your thing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Perfect for teams or anyone who’s not monolingual.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;-the-workbench-your-dev-superpower&quot;&gt;⚡️ The Workbench = Your Dev Superpower&lt;/h4&gt;
&lt;p&gt;Motia comes with a builtin dev UI called the &lt;strong&gt;Workbench&lt;/strong&gt;. It’s your local dashboard where you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Trigger steps manually&lt;/li&gt;
&lt;li&gt;Inspect inputs, outputs, and logs&lt;/li&gt;
&lt;li&gt;See how everything connects&lt;/li&gt;
&lt;li&gt;View live executions and errors&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s like DevTools, but for your backend.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;built-in-state-and-logs&quot;&gt;Built-In State and Logs&lt;/h4&gt;
&lt;p&gt;You don’t need to spin up a Redis instance or wire up logging just to track state or debug a flow.&lt;/p&gt;
&lt;p&gt;Motia gives you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple key-value state with TTL support&lt;/li&gt;
&lt;li&gt;Execution tracing&lt;/li&gt;
&lt;li&gt;Builtin observability&lt;/li&gt;
&lt;li&gt;A real-time view of what’s happening&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All out of the box. No config overload.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;What Can You Build with Motia?&lt;/p&gt;
&lt;p&gt;Honestly? A lot.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;REST APIs and microservices&lt;/li&gt;
&lt;li&gt;Background workers&lt;/li&gt;
&lt;li&gt;Internal tools&lt;/li&gt;
&lt;li&gt;AI bots and agents&lt;/li&gt;
&lt;li&gt;Data pipelines&lt;/li&gt;
&lt;li&gt;Scheduled jobs (goodbye, messy crons)&lt;/li&gt;
&lt;li&gt;Prototypes that actually scale&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the best part? All of it lives in the &lt;strong&gt;same repo&lt;/strong&gt;, with a consistent model.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;getting-started-is-super-simple&quot;&gt;Getting Started Is Super Simple&lt;/h4&gt;
&lt;p&gt;Just run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx motia@latest create -i
cd your-project
npx motia dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then head to &lt;code&gt;http://localhost:3000&lt;/code&gt; to start building in the Workbench.&lt;/p&gt;
&lt;p&gt;From there, you can create your first step (like a simple API or a scheduled task) and actually see it run live, without waiting for a deploy.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h4&gt;
&lt;p&gt;I’ve built a lot of backend projects over the years. Most of them were glued together with frameworks and tools that weren’t really meant to work together.&lt;/p&gt;
&lt;p&gt;Motia changes that. It’s one of the first tools I’ve seen that really &lt;strong&gt;treats the backend as one cohesive system&lt;/strong&gt;, not a bunch of disconnected services.&lt;/p&gt;
&lt;p&gt;If you’re into clean architecture, rapid iteration, and building with joy, I think you’ll love it too.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.motia.dev/&quot;&gt;Check it out here&lt;/a&gt; &lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/MotiaDev/motia&quot;&gt;Star the repo on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let me know what you build,  I’m genuinely curious.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/25231/the-backend-finally-makes-sense-why-im-lovingmotia</guid>
<pubDate>Mon, 24 Aug 2026 07:37:04 +0000</pubDate>
</item>
<item>
<title>Why Octopus invests in developer experience</title>
<link>https://coderlegion.com/21835/why-octopus-invests-in-developer-experience</link>
<description>&lt;p&gt;When you join Octopus, you get a great laptop and your choice from a range of docks, monitors, webcams, and input devices. You also get a home office allowance, which lets you upgrade your space and get 50% back. You may want a sit/stand desk, an awesome chair, and portrait lighting so everyone can see how delighted you are when they demo their cool new feature.&lt;/p&gt;
&lt;p&gt;What we ask in return is that you set yourself up to do your best work. Invest in your &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.hanselman.com/blog/brain-bytes-back-buns-the-programmers-priorities&quot;&gt;brain, bytes, back, and buns&lt;/a&gt;, as Scott Hanselman put it. The essential idea behind this is that when you win, Octopus wins. We all win!&lt;/p&gt;
&lt;p&gt;Yet you can throw a soggy cat at a conference, and the chances are it will splash someone from an organization with a completely different approach to developer experience. One that doesn't value the sustainable delivery of their people's best work. Why is that?&lt;/p&gt;
&lt;h3 id=&quot;a-fork-stuck-in-the-road&quot;&gt;A fork stuck in the road&lt;/h3&gt;
&lt;p&gt;As we've seen in the software industry, silos are the source of all kinds of chaos. DevOps was created when someone realized the scale of the problem caused by having two teams with conflicting goals working on opposite sides of the same problem. Leaders whipped developers up for feature throughput and wanted to hold operations teams to account for reliability.&lt;/p&gt;
&lt;p&gt;In hindsight, it's obvious that this isn't going to work, but we did it for decades. You can get halfway to DevOps just by aligning the goals. When both teams share the same target, they'll work out how to get you the rest of the way.&lt;/p&gt;
&lt;p&gt;If we zoom out on our organization, we're likely to find a similar silo/goal conflict between engineering managers and the finance team. We ask the engineering manager to build a high-performing team, while we direct finance to spend as little money as possible. This structural incentive problem leads developers to get laptops and tools that someone has negotiated to be &quot;good enough,&quot; and trust me, they aren't.&lt;/p&gt;
&lt;p&gt;When you look at developer experience through a FinBoss lens, where finance and engineering managers align around the return on investment, you'll find the optimal spend on developer tools shifts right rapidly.&lt;/p&gt;
&lt;p&gt;FinCost organizations reduce costs through standardization, commoditization, and by delaying kit refreshes for as long as possible. They often spend less than 1,000 USD on a laptop without realizing the true cost of an under-spec'd machine. Meanwhile, FinBoss organizations are seeking the 30,000 USD annual return on a 3,000 USD investment.&lt;/p&gt;
&lt;p&gt;To achieve this ROI, finance and engineering leadership work together to design policies that allow engineers to choose from a set of well-designed options. The combination of investment in great tools and individual choice in building the right setup is the path to success.&lt;/p&gt;
&lt;h3 id=&quot;tiny-visible-costs&quot;&gt;Tiny visible costs&lt;/h3&gt;
&lt;p&gt;FinCost organizations are driving decisions based on small, visible costs. Where there's a paper trail, there are savings to make: the purchase of a laptop, the training budget, and the conference invoice. These are part of the legible model, so there is no guesswork or experimental method needed to cost them. The numbers are right there on the page.&lt;/p&gt;
&lt;p&gt;Once you're managing costs, it's not uncommon to dial up the control, too. You limit options, standardize across the organization, and negotiate in bulk on everything to drive costs even lower. Compared to competitors, you could be spending 75% less on laptops, and just look at the savings from those pesky licenses and SaaS tools various teams were using. Hooray.&lt;/p&gt;
&lt;p&gt;Instead of letting engineers attend conferences they find relevant to their work, the organization negotiates a bulk purchase for a single conference. Instead of teams buzzing with diverse ideas and approaches, they all sit and watch the same talk. It's cheaper that way.&lt;/p&gt;
&lt;p&gt;A wooden fence encloses my garden. A fence lasts a long time if you give it a protective coat of wood preserver every once in a while. A tin of wood preserve costs about 20 USD and a few hours of mindful application each year. Over 5 years, I can save 100 USD by skipping the treatment. If I do this, my fence lasts about 10 years instead of 30.&lt;/p&gt;
&lt;p&gt;The cost of a tin of wood preserver is immediate and visible. The cost of replacing the fence is far higher, but it won't be visible for years. Additionally, if the fence provides value beyond privacy, like keeping a goat out of my vegetable garden, the cost of the fence failing could be the cost of my whole crop, which is even less legible to my cost control mindset.&lt;/p&gt;
&lt;p&gt;If you're creating software, it's likely to be more valuable than a fence. In fact, it should be giving you returns multiple times your investment. It's like a golden goose. You feed it well, and you get regular, valuable deliveries. If you had a golden goose, you wouldn't try to save on food costs if it reduced the flow of golden eggs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=11199186589923672688&quot; alt=&quot;A cartoon showing a character trying to save money by reducing the cost of feeding a golden goose. The goose doesn't survive this experiment.&quot;&gt;&lt;/p&gt;
&lt;p&gt;The same logic plays out with training. A FinCost organization cuts the training budget because the line item is visible and the return isn't. Individual engineers stop attending relevant courses, and teams miss out on the steady accumulation of skill that comes from ongoing, targeted learning. Nobody raises a purchase order for &quot;capability that didn't grow this year.&quot;&lt;/p&gt;
&lt;p&gt;Then something goes wrong. Delivery is slow, the codebase is a mess, or a competitor pulls ahead. Someone decides the answer is transformation, and that means Scaled Agile, or whatever flavor of desperation is in fashion in exec suites at the time.&lt;/p&gt;
&lt;p&gt;So the whole department gets booked onto an external SAFe course. Not one or two people who need it. Everyone. The invoice lands, and it's eye-watering: many times what a thoughtful, ongoing training program would have cost across the same period. The organization that was too cautious to spend 500 USD on a course people wanted just spent 50,000 USD on one nobody asked for.&lt;/p&gt;
&lt;p&gt;This is the hidden tax of FinCost thinking. Small, visible costs get cut. The problems that those small costs would have prevented quietly compound. Eventually, the pressure releases all at once, in an expensive, rushed, and hard-to-argue-against way, because now there's a crisis with a visible price tag.&lt;/p&gt;
&lt;p&gt;The tin of wood preserver was the right investment all along.&lt;/p&gt;
&lt;h3 id=&quot;the-invisible-people-hours&quot;&gt;The invisible people-hours&lt;/h3&gt;
&lt;p&gt;Developers work around 40 hours a week. Stripe's Developer Coefficient found that productivity friction can eat up roughly half of those hours. That's the time that evaporates before a single line of useful code is written. Across the global developer workforce, Stripe put a number on that loss: 300 billion USD. It's worth noting that only 85 billion USD of this is attributable to bad code. The rest is pure friction: slow tools, broken environments, waiting for builds, wrestling with under-spec'd machines. Productivity means more than writing code faster.&lt;/p&gt;
&lt;p&gt;That friction has a texture. It's a developer losing flow because their laptop is thrashing memory, and they've lost the thread of what they were thinking.&lt;/p&gt;
&lt;p&gt;It's waiting 10 minutes for a build that would have completed in 2 minutes on a faster machine. It's the workarounds you built because the approved tool wasn't good enough, which obliterates hours of your week for maintenance. It's the skilled engineers who start looking for a new role because the environment makes them feel like you don't take their work seriously.&lt;/p&gt;
&lt;p&gt;None of this appears on a purchase order. None of it shows up in a variance report. It just quietly drains the value your software could be creating.&lt;/p&gt;
&lt;p&gt;There's also an upside case, not just a loss case. Software that ships faster captures more market share. Developers who stay in flow write better code with fewer bugs, which means less rework and fewer incidents. A high-performing team attracts other high performers. The return on investing in developer experience isn't just &quot;we lose less time&quot;; it's sales opportunities, reduced churn, higher product quality, and a compounding advantage over competitors who are still buying 800 USD laptops and calling it responsible.&lt;/p&gt;
&lt;p&gt;When you focus on cost control, there's a ceiling on how much you can save. When you look for return on investment, there's no equivalent ceiling on how much you can gain.&lt;/p&gt;
&lt;h3 id=&quot;the-cfo-lens&quot;&gt;The CFO lens&lt;/h3&gt;
&lt;p&gt;When I asked Sammy, our CFO, about why we invest in people, powerful machines, and great tools, he said: &quot;At Octopus, we think about equipment as a productivity tool. Developers are one of our most expensive and constrained resources. If spending a few extra thousand dollars on a fast machine and proper screen space saves time, reduces cognitive load, or keeps someone in flow more often, it pays for itself very quickly.&quot;&lt;/p&gt;
&lt;p&gt;That means our finance team doesn't ask &quot;What's the cheapest laptop we can buy?&quot; Instead, they ask, &quot;What setup helps this person do their best work?&quot; From a finance perspective, this is about a high-ROI spend, not indulgence.&lt;/p&gt;
&lt;p&gt;Octopus is running the FinBoss playbook, which aligns finance and leadership in empowering employees to do their best work. That means expanding what you're willing to measure so that you can balance the visible costs with traditionally invisible returns.&lt;/p&gt;
&lt;p&gt;The responsibility for providing this environment for employees rests with all leaders, including Sammy, and is part of the deal employees have with the company; we'll give you the best environment and tools if you give us the greatest work of your career.&lt;/p&gt;
&lt;h3 id=&quot;the-reckoning&quot;&gt;The reckoning&lt;/h3&gt;
&lt;p&gt;If we've ever met, I've likely mentioned &lt;a rel=&quot;nofollow&quot; href=&quot;https://dora.dev/research/&quot;&gt;DORA's research&lt;/a&gt;. I'm a super-fan of their State of DevOps reports, because they provide us techniques, practices, and outcomes that are all linked through complex relationships. The model shows that transformational leadership, lean product management, and Continuous Delivery drive software delivery performance and organizational outcomes.&lt;/p&gt;
&lt;p&gt;While many of the capabilities in the DORA model are technical, many others relate to leadership. Particularly relevant to developer experience are generative organizational culture, transformational leadership, empowering teams to choose tools, team experimentation, and a learning culture. You can read about these and more on the &lt;a rel=&quot;nofollow&quot; href=&quot;https://dora.dev/capabilities/&quot;&gt;DORA website&lt;/a&gt;. Together, they back up the FinBoss concept with tens of thousands of survey samples that support the case.&lt;/p&gt;
&lt;p&gt;The question is: Which organization are you now, and which do you want to be? Is it FinCost, operating myopically against the bottom line, or FinBoss, sharing the responsibility for developer experience and employee productivity? The fork in the road was never a choice. We know FinCost is a dead end, and the benefits of FinBoss aren't soft claims; they're measurable outcomes.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21835/why-octopus-invests-in-developer-experience</guid>
<pubDate>Fri, 03 Jul 2026 12:47:04 +0000</pubDate>
</item>
<item>
<title>The Developer Owns the UX. The AI Owns the Code.</title>
<link>https://coderlegion.com/18510/the-developer-owns-the-ux-the-ai-owns-the-code</link>
<description>&lt;p&gt;My mom does bead art. The kind where you sit with a tray of tiny plastic beads and, over hours — sometimes days — assemble them into an intricate portrait or devotional motif. It's meditative, precise, and deeply personal.&lt;/p&gt;
&lt;p&gt;The bottleneck has always been the pattern. You can't look at a photograph and start placing beads. You need to know &lt;em&gt;exactly&lt;/em&gt; which bead goes where, in what color, on a grid that maps to the physical constraints of the project: how wide it is, how many colors of beads you've bought, how coarse or fine the detail needs to be.&lt;/p&gt;
&lt;p&gt;She was doing this by eye, or with rough printouts. I kept thinking: &lt;em&gt;there has to be a better way.&lt;/em&gt; So I opened Gemini and started a conversation.&lt;/p&gt;
&lt;p&gt;What came out of that is &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ranji2612/beads_design&quot;&gt;BeadGen&lt;/a&gt; — a fully local, zero-dependency browser tool that converts any photo into a ready-to-stitch bead pattern. No backend. No npm. No install. You open an HTML file and use it.&lt;/p&gt;
&lt;p&gt;But this post isn't really about the tool. It's about something I learned while building it: &lt;strong&gt;when you let AI write the code, the developer's most important job becomes the experience.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-it-actually-does&quot;&gt;What It Actually Does&lt;/h3&gt;
&lt;p&gt;Before the technical deep-dive, here's the simplest way to show it.&lt;/p&gt;
&lt;p&gt;Take the Golden Gate Bridge at sunset — rich gradients, a complex rust-red structure, water, sky, fog, warm light hitting the cables at an angle. Thousands of colors.&lt;/p&gt;
&lt;p&gt;Run it through BeadGen at 150 beads wide, no gradient mode on, full color palette.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bheaqf2n7q8thn7fs96p.png&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;Every circle is a bead. Every color in that output is a real, distinct bead color a crafter would need to source and place by hand. The structure of the bridge is preserved. The mood of the sunset is preserved. The complexity is &lt;em&gt;managed&lt;/em&gt; — reduced to something a human can actually execute, one bead at a time.&lt;/p&gt;
&lt;p&gt;That transformation — from photograph to stitchable grid — is the whole product.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-ai-owns-the-code-actually-means&quot;&gt;What &quot;AI Owns the Code&quot; Actually Means&lt;/h3&gt;
&lt;p&gt;I want to be precise here, because &quot;AI-assisted development&quot; has become a meaningless phrase. Everyone says it now. Here's what it meant for me on this project:&lt;/p&gt;
&lt;p&gt;I wrote very little code from scratch. I used Gemini as the primary implementer — describing what I needed, reviewing what came back, asking it to revise or explain. The logic for color quantization, the Canvas API rendering pipeline, the pixel buffer manipulation — most of that was AI-native code that I read, understood, and occasionally redirected, but didn't author line by line.&lt;/p&gt;
&lt;p&gt;What I &lt;em&gt;didn't&lt;/em&gt; delegate: every decision about what the tool should feel like.&lt;/p&gt;
&lt;p&gt;How many controls is too many? Where does the slider sit? What does &quot;No Gradient Mode&quot; actually mean to someone who isn't a developer? What should the output look like when it downloads? Should error states be loud or quiet?&lt;/p&gt;
&lt;p&gt;None of that came from Gemini. All of it required me to stay in the room, stay opinionated, and push back when the generated UI drifted toward &quot;technically correct but confusing to use.&quot;&lt;/p&gt;
&lt;p&gt;That division of labor — AI on implementation, human on experience — turned out to be the whole game.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-technical-problem-because-it-s-interesting-&quot;&gt;The Technical Problem (Because It's Interesting)&lt;/h3&gt;
&lt;p&gt;BeadGen solves three sub-problems in sequence:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Resolution mapping.&lt;/strong&gt; A bead project has a fixed width in bead count — say, 150 beads wide. The photo needs to be downsampled to that exact grid resolution, with aspect ratio preserved.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Color quantization.&lt;/strong&gt; The Golden Gate photo has thousands of colors. My mom's bead collection has maybe 10. The image's palette has to collapse to that count without destroying the image.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Rendering.&lt;/strong&gt; Each cell in the grid gets drawn as a filled circle (the bead shape), not a square pixel, on a canvas the user can download.&lt;/p&gt;
&lt;p&gt;The interesting one is color quantization. The naive approach — round every color to the nearest bucket — looks terrible. You lose the soul of the image because you're treating all of color space uniformly, when an image's color distribution is wildly uneven.&lt;/p&gt;
&lt;p&gt;The right approach is the &lt;strong&gt;Median Cut algorithm&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Put all pixels in one bucket.&lt;/li&gt;
&lt;li&gt;Find which color channel (R, G, or B) has the widest range across all pixels in the bucket.&lt;/li&gt;
&lt;li&gt;Sort by that channel and split at the median.&lt;/li&gt;
&lt;li&gt;Recurse until you have N buckets.&lt;/li&gt;
&lt;li&gt;Each bucket's representative color is the average of its pixels.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The result is that color splits happen &lt;em&gt;where the actual data is most varied&lt;/em&gt; — not uniformly across abstract color space. The Golden Gate image has a massive warm cluster (the bridge, sunset light) and a separate cool cluster (the bay, the fog, the sky). Median Cut finds that divide naturally and allocates palette slots accordingly. The rust-red cables stay rust-red. The blue-gray water stays blue-gray.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;function nearestColor(r, g, b, palette) {
  let minDist = Infinity;
  let closest = palette[0];
  for (const color of palette) {
    const dist =
      (r - color.r) ** 2 +
      (g - color.g) ** 2 +
      (b - color.b) ** 2;
    if (dist &amp;lt; minDist) {
      minDist = dist;
      closest = color;
    }
  }
  return closest;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Euclidean distance in RGB space isn't perceptually perfect — LAB color space would be more accurate — but it's fast, dependency-free, and more than sufficient for bead-level fidelity. I knew about the tradeoff. I chose simplicity deliberately. That was a developer decision, not an AI one.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-feature-my-mom-asked-for&quot;&gt;The Feature My Mom Asked For&lt;/h3&gt;
&lt;p&gt;There's one feature in BeadGen I'm particularly glad I added: &lt;strong&gt;No Gradient Mode&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Photos have gradients everywhere — smooth transitions between light and shadow, color bleeding, soft backgrounds. The Golden Gate sunset is practically nothing &lt;em&gt;but&lt;/em&gt; gradient. In a photograph, that's beautiful. In a bead pattern, it's a nightmare. You'd need 80 colors to represent that sky faithfully, and no one has 80 colors of beads.&lt;/p&gt;
&lt;p&gt;No Gradient Mode posterizes the output. After quantization, it snaps colors more aggressively to the palette and flattens subtle transitions into solid bands. The pattern looks more graphic, more like flat illustration — and is actually &lt;em&gt;stitchable&lt;/em&gt; by a human working from a printed sheet.&lt;/p&gt;
&lt;p&gt;The AI didn't suggest this. My mom did. She looked at her first output and said the gradients were too much.&lt;/p&gt;
&lt;p&gt;That's the feature you add when your user is in the room. And that's exactly the kind of thing that wouldn't exist if I'd treated the AI as the product owner instead of the implementer.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-stack-deliberately-aggressively-simple&quot;&gt;The Stack: Deliberately, Aggressively Simple&lt;/h3&gt;
&lt;p&gt;BeadGen is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vanilla JavaScript&lt;/li&gt;
&lt;li&gt;HTML5 Canvas API&lt;/li&gt;
&lt;li&gt;Zero dependencies&lt;/li&gt;
&lt;li&gt;Zero build step&lt;/li&gt;
&lt;li&gt;&lt;code&gt;index.html&lt;/code&gt; + &lt;code&gt;script.js&lt;/code&gt; + &lt;code&gt;style.css&lt;/code&gt;, runs off your local file system — literally &lt;code&gt;file:///your-path/index.html&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This was a firm decision. My mom needed to &lt;em&gt;use&lt;/em&gt; this tool, not install it. That means no localhost server, no terminal, no Python environment. She opens a file in Chrome. Done.&lt;/p&gt;
&lt;p&gt;The Canvas API handles everything:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;drawImage()&lt;/code&gt; to resample the photo to bead-grid resolution&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getImageData()&lt;/code&gt; to read pixel values for quantization&lt;/li&gt;
&lt;li&gt;&lt;code&gt;arc()&lt;/code&gt; to draw each bead as a filled circle&lt;/li&gt;
&lt;li&gt;&lt;code&gt;toDataURL()&lt;/code&gt; to export the result as a downloadable PNG&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Working with raw pixel buffers is verbose and unforgiving, like writing assembly. But it keeps the whole thing self-contained, fast, and completely offline. Those are UX decisions first, technical decisions second.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;where-i-had-to-stay-opinionated&quot;&gt;Where I Had to Stay Opinionated&lt;/h3&gt;
&lt;p&gt;Here's where I want to be honest about the limits of delegating to AI.&lt;/p&gt;
&lt;p&gt;Gemini was excellent at implementing what I described. It was not good at knowing &lt;em&gt;what&lt;/em&gt; to describe. When left to generate UI scaffolding on its own, it produced things that were &lt;em&gt;functional but unintuitive&lt;/em&gt; — too many options exposed at once, labels that made sense to a developer but not to someone who just wants to make a bead pattern, layouts that were complete but crowded.&lt;/p&gt;
&lt;p&gt;Every time I let a generated UI suggestion through without interrogating it, my mom got confused. Every time I pushed back — &quot;this should be one toggle, not three settings,&quot; &quot;this label needs to say what it does, not what it is&quot; — the tool got better.&lt;/p&gt;
&lt;p&gt;The AI wrote the code correctly. I had to tell it what &quot;correct&quot; meant for this user.&lt;/p&gt;
&lt;p&gt;That gap — between code that works and an experience that works — is where the developer still has to show up. And I don't think that gap is going away anytime soon.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-s-next&quot;&gt;What's Next&lt;/h3&gt;
&lt;p&gt;A few things on the roadmap:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Perceptual color distance&lt;/strong&gt; — Switching from Euclidean RGB to CIEDE2000 in LAB color space for more accurate palette matching, especially for skin tones and subtle warm-to-cool transitions like that bridge sunset.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bead inventory input&lt;/strong&gt; — Instead of &quot;give me N colors,&quot; let the user input their actual bead colors and map to those exactly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Print layout export&lt;/strong&gt; — A PDF with row-by-row bead counts and a color legend, formatted for A4/Letter printing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Row-by-row guided mode&lt;/strong&gt; — Step through one row at a time with bead counts, similar to knitting pattern notation.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;try-it&quot;&gt;Try It&lt;/h3&gt;
&lt;p&gt;The source is on GitHub: &lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ranji2612/beads_design&quot;&gt;ranji2612/beads_design&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Clone it, open &lt;code&gt;index.html&lt;/code&gt; in a browser, upload a photo. No setup. Runs entirely offline.&lt;/p&gt;
&lt;p&gt;If you're a crafter and you make something with it, I'd genuinely love to see it. If you're a developer and you want to tackle LAB-space color distance or a print export feature, PRs are open.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;AI wrote most of the code. I designed the experience. My mom makes the patterns. That's a pretty good division of labor.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/18510/the-developer-owns-the-ux-the-ai-owns-the-code</guid>
<pubDate>Thu, 21 May 2026 05:36:05 +0000</pubDate>
</item>
<item>
<title> I built askdiff — a Claude Code skill that lets you ask questions to the same session that wrote the code</title>
<link>https://coderlegion.com/18198/built-askdiff-claude-code-skill-that-lets-ask-questions-the-same-session-that-wrote-the-code</link>
<description>&lt;h3 id=&quot;the-problem-i-kept-running-into&quot;&gt;The problem I kept running into&lt;/h3&gt;
&lt;p&gt;Using Claude Code in the past couple of months I have noticed a clear bottleneck in my workflow - reviewing code written by AI.&lt;/p&gt;
&lt;p&gt;My workflow looked like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Finish a Claude Code session&lt;/li&gt;
&lt;li&gt;Open a draft PR to review the diff&lt;/li&gt;
&lt;li&gt;Hit a question on a specific line&lt;/li&gt;
&lt;li&gt;Copy file name + line numbers back into Claude&lt;/li&gt;
&lt;li&gt;Try to help the session to remember the context&lt;/li&gt;
&lt;li&gt;Repeat&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Then I realized something: &lt;strong&gt;in the pre-AI world, I never did this.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I never took diffs back to the code author. I just left a comment &lt;br&gt;
in the PR and the author answered directly, because they had full &lt;br&gt;
context of why and what.&lt;/p&gt;
&lt;p&gt;So I built askdiff.&lt;/p&gt;
&lt;h3 id=&quot;what-askdiff-does&quot;&gt;What askdiff does&lt;/h3&gt;
&lt;p&gt;Askdiff is a Claude Code skill + an NPM package that opens a GitHub PR-style diff viewer in your browser, attached to the same Claude Code session that wrote the code.&lt;/p&gt;
&lt;p&gt;Launch /askdiff from any Claude Code session and it will open the working directory diff in a UI attached to the Claude Code session.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0xhx4j86azflmy5um2u.gif&quot; alt=&quot;askdiff demo&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;how-to-try-it&quot;&gt;How to try it&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd /path/to/your/project
npx -y askdiff install-skill

# Or, install user-level (available from any project):
npx -y askdiff install-skill --global
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then run &lt;code&gt;/askdiff&lt;/code&gt; from any Claude Code session.&lt;/p&gt;
&lt;h4 id=&quot;-askdiff-with-natural-language-descriptions-for-diff-and-session&quot;&gt;/askdiff with natural language descriptions for diff and session&lt;/h4&gt;
&lt;p&gt;Askdiff can also be launched by describing the diff and the session you want it to be attached. Let's say you have made a change days ago and it had a dedicated session that has all the context. You can do&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;/askdiff the commit where we implemented auth attached to the session that wrote it
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8sc5akob1v2v3nh1doc.gif&quot; alt=&quot;askdiff demo for NL descriptors&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-technical-bit&quot;&gt;The technical bit&lt;/h3&gt;
&lt;p&gt;Askdiff uses &lt;code&gt;claude --resume&lt;/code&gt; &lt;em&gt;without&lt;/em&gt; &lt;code&gt;--fork-session&lt;/code&gt;, so, if launched or attached to a session that has the context your question contains all the relevant information that the AI needs to answer it.&lt;/p&gt;
&lt;p&gt;This means if you ask &quot;why did you use a Set here instead of an &lt;br&gt;
array?&quot;, the answer will reference the actual reasoning from when &lt;br&gt;
the code was written, not a generic explanation.&lt;/p&gt;
&lt;h3 id=&quot;what-s-next-1&quot;&gt;What's next&lt;/h3&gt;
&lt;p&gt;Currently Claude Code only, no Anthropic API key required, no configuration.&lt;/p&gt;
&lt;p&gt;The repo is open source: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/narghev/askdiff&quot;&gt;https://github.com/narghev/askdiff&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I'm still using askdiff daily and refining the UI and the skill itself. &lt;/p&gt;
&lt;p&gt;If you're using Claude Code in your team workflow — how are you reviewing AI-generated code today? Is the back-and-forth between PR and Claude a pain for you too?&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/18198/built-askdiff-claude-code-skill-that-lets-ask-questions-the-same-session-that-wrote-the-code</guid>
<pubDate>Mon, 18 May 2026 06:23:23 +0000</pubDate>
</item>
<item>
<title>Build an AI-Powered Developer Portal with Backstage and .NET</title>
<link>https://coderlegion.com/17940/build-an-ai-powered-developer-portal-with-backstage-and-net</link>
<description>&lt;h3 id=&quot;build-an-ai-powered-developer-portal-with-backstage-and-net&quot;&gt;Build an AI-Powered Developer Portal with Backstage and .NET&lt;/h3&gt;
&lt;p&gt;Want to apply AI, not just read about it? Most tutorials stop at a &quot;Hello World&quot; chatbot. We are going to build something that actually solves a common engineering headache: stale documentation.&lt;/p&gt;
&lt;h4 id=&quot;who-this-is-for&quot;&gt;Who this is for&lt;/h4&gt;
&lt;p&gt;This guide is for platform engineers and .NET developers who need to organize a growing software landscape without forcing teams to manually write YAML files.&lt;/p&gt;
&lt;h4 id=&quot;what-you-will-build&quot;&gt;What you will build&lt;/h4&gt;
&lt;p&gt;You will build a &lt;strong&gt;dynamic developer portal&lt;/strong&gt; using &lt;a rel=&quot;nofollow&quot; href=&quot;https://backstage.io/&quot;&gt;Backstage&lt;/a&gt; that automatically populates its service catalog. We will use a .NET CLI tool to scan source code and use local AI (&lt;a rel=&quot;nofollow&quot; href=&quot;https://ollama.com/&quot;&gt;Ollama&lt;/a&gt;) to generate summaries.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Source repo:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/bgener/demo-backstage-catalog-generator&quot;&gt;demo-backstage-catalog-generator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Constraint:&lt;/strong&gt; We use local inference only. No source code ever leaves your machine.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Have you ever needed to update a service, but forgot what it does? Or spent time trying to understand code you have not touched in months? We usually solve this with a README.md that nobody updates, or a wiki nobody keeps current.&lt;/p&gt;
&lt;p&gt;An Internal Developer Portal (IDP) solves this by making the software landscape visible, but only if the data is fresh. Automation is the only way to avoid the &quot;stale metadata&quot; trap.&lt;/p&gt;

**Want to skip ahead?** Check out the [complete working demo on
GitHub](https://github.com/bgener/demo-backstage-catalog-generator) with all
the code ready to run.

&lt;h4 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h4&gt;
&lt;p&gt;Before we start, make sure you have the following installed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://dotnet.microsoft.com/en-us/download&quot;&gt;.NET SDK 8+&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://nodejs.org/&quot;&gt;Node.js&lt;/a&gt; (includes &lt;code&gt;npx&lt;/code&gt; and &lt;code&gt;yarn&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://ollama.com/&quot;&gt;Ollama&lt;/a&gt; with the &lt;code&gt;llama3:8b&lt;/code&gt; model pulled&lt;/li&gt;
&lt;li&gt;A GitHub account (for hosting and deployment)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;why-does-an-internal-developer-portal-matter-&quot;&gt;Why Does an Internal Developer Portal Matter?&lt;/h4&gt;
&lt;p&gt;The term &quot;Internal Developer Portal&quot; (IDP) can be a little misleading, since it sounds like a tool exclusively for developers only. In reality, it functions as an &lt;strong&gt;internal organizational portal focused entirely on your software portfolio&lt;/strong&gt;. Unlike a general-purpose SharePoint site where everything is dumped in one place and nothing is easy to find, an IDP is deliberately narrow in scope. It covers your software landscape and nothing else, which is exactly what makes it powerful.&lt;/p&gt;
&lt;p&gt;An IDP becomes the &lt;strong&gt;single source of truth&lt;/strong&gt; for your engineering organization. It answers critical questions across every role:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Engineers:&lt;/strong&gt; Which services exist, who owns them, what they do, and where the APIs are.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Team leads and architects:&lt;/strong&gt; Team composition, squad ownership, and architectural decisions with their rationale.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;New joiners:&lt;/strong&gt; How to get up to speed on a codebase they have never seen.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Platform and operations teams:&lt;/strong&gt; What is running in production, who is responsible, and the lifecycle status.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Beyond just listing services, a mature IDP centralizes &lt;strong&gt;Architecture Decision Records (ADRs)&lt;/strong&gt;. I'd argue those are more valuable than the service catalog itself, because they capture &lt;em&gt;why&lt;/em&gt; a decision was made. Without a central place to surface them, they end up in forgotten wiki pages or git repositories nobody checks.&lt;/p&gt;
&lt;p&gt;The challenge is keeping all of this populated and accurate. If you rely on engineers to manually maintain metadata YAML files, the data grows stale within weeks. Automation is the only sustainable path.&lt;/p&gt;
&lt;h4 id=&quot;formulating-the-architecture&quot;&gt;Formulating the Architecture&lt;/h4&gt;
&lt;p&gt;Here's the plan to extract metadata from source code and present it visually:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Backstage:&lt;/strong&gt; the UI layer where engineers browse and discover services, APIs, documentation, and team ownership&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.NET Core:&lt;/strong&gt; a CLI tool that scans project folders, extracts metadata, and generates Backstage-compatible YAML&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ollama:&lt;/strong&gt; runs AI inference locally. No source code leaves the machine, no API costs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Static hosting:&lt;/strong&gt; deploy to Netlify, Azure Static Web Apps, or any provider of your choice&lt;/li&gt;
&lt;/ul&gt;

*Why Ollama?* Because it runs locally and you do not want to expose your code
to the AI agents over the public internet. You do not know what and how they
use it for, and it does not feel safe. If your employer finds out, you're
done.

&lt;h4 id=&quot;setting-up-the-project-infrastructure&quot;&gt;Setting Up the Project Infrastructure&lt;/h4&gt;
&lt;p&gt;You can either follow along and build everything from scratch, or clone the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/bgener/demo-backstage-catalog-generator&quot;&gt;demo repository&lt;/a&gt; to get started immediately.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To clone the demo:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/bgener/demo-backstage-catalog-generator.git
cd demo-backstage-catalog-generator
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;To build from scratch&lt;/strong&gt;, start by downloading and running the LLM model we will use in this guide:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ollama pull llama3:8b
ollama serve
&lt;/code&gt;&lt;/pre&gt;

We use `llama3:8b` specifically. It is significantly faster for local
inference than the full-size model and produces more consistent, concise
output for our use case. If you have a powerful GPU, feel free to use `llama3`
instead.

&lt;p&gt;Next, scaffold the baseline .NET services. We’ll create one Web API and one MVC project:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mkdir Backstage-Dev-Portal
cd Backstage-Dev-Portal

dotnet new webapi -n ServiceA
dotnet new mvc -n ServiceB

dotnet new sln -n Backstage-Dev-Portal
dotnet sln add ServiceA/ServiceA.csproj
dotnet sln add ServiceB/ServiceB.csproj
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can replace the default controllers with real logic later. These raw services represent the uncataloged microservices in your organization.&lt;/p&gt;
&lt;h4 id=&quot;building-a-smart-catalog-generator-in-net&quot;&gt;Building a Smart Catalog Generator in .NET&lt;/h4&gt;
&lt;p&gt;We will build a .NET CLI tool using &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/awaescher/OllamaSharp&quot;&gt;OllamaSharp&lt;/a&gt;. It scans each project, sends relevant files to the local AI model, and generates a single &lt;code&gt;catalog-info.yaml&lt;/code&gt; file containing all services, ready for Backstage to consume.&lt;/p&gt;
&lt;p&gt;Create the tool and add the required package:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet new console -n ProjectSummarizer
cd ProjectSummarizer
dotnet add package OllamaSharp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of sending every file to the AI, we take a smarter approach to avoid token limits and save compute time. We will send only &lt;code&gt;*.csproj&lt;/code&gt;, &lt;code&gt;Program.cs&lt;/code&gt;, and the folder structure. This is all the context the AI needs to understand the project structure and purpose.&lt;/p&gt;
&lt;p&gt;Replace &lt;code&gt;Program.cs&lt;/code&gt; with the implementation below. The full version is in the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/bgener/demo-backstage-catalog-generator&quot;&gt;demo repository&lt;/a&gt;. Here we focus on the key parts.&lt;/p&gt;
&lt;p&gt;First, set up the Ollama client and configure the system prompt. This is the most fragile part of the chain: the system prompt has to force the model into a YAML-safe format without it hallucinating markdown backticks:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;var ollamaApiClient = new OllamaApiClient(
    new Uri(&quot;http://localhost:11434&quot;)) { SelectedModel = &quot;llama3:8b&quot; };

var chat = new Chat(ollamaApiClient, systemPrompt:
    &quot;You are a technical documentation assistant. &quot; +
    &quot;You produce concise, YAML-safe summaries of .NET projects. &quot; +
    &quot;Output only plain text, no markdown, no bullet points, no quotes, no colons, no newlines.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of sending every file to the AI, we only send &lt;code&gt;*.csproj&lt;/code&gt;, &lt;code&gt;Program.cs&lt;/code&gt;, and the folder structure. This is all the context the model needs.&lt;/p&gt;

**Prompt sanitization is critical.** If your `Program.cs` contains complex
string literals or nested colons, the AI might pass them through to your YAML,
breaking the Backstage parser. Always sanitize the output before writing the
file.

&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;var sb = new StringBuilder();
sb.AppendLine($&quot;Project: {projectName}&quot;);
sb.AppendLine(&quot;Folder structure:&quot;);
AppendFolderStructure(projectDir, sb, &quot;&quot;);
sb.AppendLine(File.ReadAllText(csprojPath));

var programPath = Directory.GetFiles(projectDir, &quot;Program.cs&quot;, SearchOption.AllDirectories)
    .FirstOrDefault();
if (programPath != null)
    sb.AppendLine(File.ReadAllText(programPath));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The prompt itself uses few-shot examples to guide the model toward the output format we want:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;var prompt = &quot;Summarize the project in 1-2 sentences based on the files provided. &quot; +
             &quot;Do not output anything else. &quot; +
             &quot;Examples of good output: &quot; +
             &quot;REST API service providing weather forecasts with temperature data\n&quot; +
             &quot;ASP.NET MVC application with React frontend for managing todo items\n\n&quot;
             + sb.ToString();

await foreach (var token in chat.SendAsync(prompt, cts.Token))
    summaryBuilder.Append(token);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, each summary is sanitized and assembled into a Backstage-compatible YAML entry:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;var summary = summaryBuilder.ToString().Trim()
    .Replace(&quot;\n&quot;, &quot; &quot;).Replace(&quot;:&quot;, &quot; -&quot;).Replace(&quot;\&quot;&quot;, &quot;'&quot;);

var yamlEntry = $@&quot;
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: {projectName.ToLowerInvariant()}
  description: &quot;&quot;{summary}&quot;&quot;
spec:
  type: service
  lifecycle: production
  owner: group:default/engineering&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run the generator against the target directory (use &lt;code&gt;.&lt;/code&gt; if you are already in the project root):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet run --project ProjectSummarizer -- .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should see the AI streaming its summaries in real time:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8w473r4i4y839n02e56.png&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;Most of the real work here is figuring out the prompt. Even a tiny change can produce a completely different output. I encourage you to experiment with the system prompt and the user prompt to see how it affects quality. That is the real learning here.&lt;/p&gt;
&lt;h4 id=&quot;integrating-the-ai-catalog-with-backstage&quot;&gt;Integrating the AI Catalog with Backstage&lt;/h4&gt;
&lt;p&gt;With the &lt;code&gt;catalog-info.yaml&lt;/code&gt; ready, we can integrate it into a Backstage instance. Install Backstage:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx @backstage/create-app
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Follow the prompts to name it &lt;code&gt;dev-portal&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now point Backstage to your generated catalog file. Open &lt;code&gt;app-config.yaml&lt;/code&gt; in the &lt;code&gt;dev-portal&lt;/code&gt; directory and add the following under the &lt;code&gt;catalog&lt;/code&gt; section:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;catalog:
  locations:
    - type: file
      target: ../Backstage-Dev-Portal/catalog-info.yaml
      rules:
        - allow: [Component]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This tells Backstage where to find the AI-generated service metadata. The &lt;code&gt;target&lt;/code&gt; path is relative to the Backstage root directory. Adjust it to point to wherever your generator wrote the &lt;code&gt;catalog-info.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To run it locally:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd dev-portal
yarn dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Open &lt;code&gt;http://localhost:3000&lt;/code&gt; in your browser. You should see all your services listed in the &lt;strong&gt;Software Catalog&lt;/strong&gt; with AI-generated summaries visible in the description column.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1gnd3uy6sjadiwto76lv.png&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;deploying-the-portal&quot;&gt;Deploying the Portal&lt;/h4&gt;
&lt;p&gt;To host this, build your portal as a static site:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;yarn build:static
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Push the output to GitHub and deploy to any &lt;strong&gt;static hosting provider&lt;/strong&gt;: Netlify, Azure Static Web Apps, Vercel, or even self-hosted on Kubernetes. Set the build command to &lt;code&gt;yarn build:static&lt;/code&gt; and the publish directory to &lt;code&gt;dist&lt;/code&gt;.&lt;/p&gt;

A static Backstage build is great for read-only catalogs. If you need dynamic
features like **authentication**, **real-time plugin backends**, or **write
operations**, you will need to deploy the full Backstage backend as a Node.js
service instead.

&lt;p&gt;The part that is easy to miss is that a static Backstage portal has no live catalog refresh. The catalog is baked at build time, so there is always a lag between a code change and the portal showing it.&lt;/p&gt;
&lt;h3 id=&quot;automating-with-ci-cd&quot;&gt;Automating with CI/CD&lt;/h3&gt;
&lt;p&gt;The catalog only stays current if the generator runs automatically. Here is a GitHub Actions workflow that regenerates summaries on every push to &lt;code&gt;main&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;name: Update Backstage Catalog
on:
  push:
    branches: [main]

jobs:
  generate-catalog:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: ‘8.0.x’

      - name: Install and start Ollama
        run: |
          curl -fsSL https://ollama.com/install.sh | sh
          ollama serve &amp;amp;
          sleep 5
          ollama pull llama3:8b

      - name: Generate catalog
        run: dotnet run --project ProjectSummarizer -- &quot;$GITHUB_WORKSPACE&quot;

      - name: Commit updated catalog
        run: |
          git config user.name &quot;github-actions&quot;
          git config user.email &quot;*Emails are not allowed*&quot;
          git add catalog-info.yaml
          git diff --cached --quiet || git commit -m &quot;chore: regenerate AI catalog summaries&quot;
          git push
&lt;/code&gt;&lt;/pre&gt;

**CI Performance:** Running Ollama in CI uses CPU-only inference by default. A
`llama3:8b` summary takes about 20-30 seconds per project on a standard GitHub
runner. For a large monorepo, your CI bill will spike. Consider using a
persistent self-hosted runner with a GPU if you scale this.

&lt;h4 id=&quot;final-thoughts-1&quot;&gt;Final thoughts&lt;/h4&gt;
&lt;p&gt;Automate the metadata generation where the code lives, and keep the UI (Backstage) as a thin, static client. That is the whole trick. Once those two are separate, the &quot;stale documentation&quot; problem mostly goes away.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use narrow context:&lt;/strong&gt; Don't send the whole repo. Files like &lt;code&gt;Program.cs&lt;/code&gt; and &lt;code&gt;*.csproj&lt;/code&gt; are usually enough context for the model.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sanitize strictly:&lt;/strong&gt; AI output is non-deterministic. Always strip colons and newlines before writing to YAML.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Start static:&lt;/strong&gt; Read-only is much easier to maintain. Add a backend only when you actually need write operations or auth.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I would not use this in production unless I had tested the sanitization logic against a few real codebases first. The &lt;code&gt;Replace&lt;/code&gt; calls that strip colons and newlines are intentionally minimal. They break on YAML with complex string values, like connection strings or environment variable blocks.&lt;/p&gt;
&lt;h3 id=&quot;faq&quot;&gt;FAQ&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Can I use OpenAI instead of Ollama?&lt;/strong&gt;&lt;br&gt;
Yes, but you will be sending your source code (or at least your &lt;code&gt;Program.cs&lt;/code&gt;) to a third party. Use a local model if security is a concern.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does this replace README files?&lt;/strong&gt;&lt;br&gt;
No. It replaces the &quot;Service Directory&quot; that usually lives in a spreadsheet. It points engineers to the README they actually need.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I handle project renames?&lt;/strong&gt;&lt;br&gt;
The generator uses the folder or &lt;code&gt;.csproj&lt;/code&gt; name. If you rename them, Backstage will see it as a new component unless you map the identity stably.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;I help teams build exactly this kind of internal tooling, from developer portals to platform engineering. &lt;a rel=&quot;nofollow&quot; href=&quot;https://blog.bgener.nl/resume&quot;&gt;See my work&lt;/a&gt; or &lt;a rel=&quot;nofollow&quot; href=&quot;https://blog.bgener.nl/contact&quot;&gt;get in touch&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/17940/build-an-ai-powered-developer-portal-with-backstage-and-net</guid>
<pubDate>Fri, 15 May 2026 09:51:01 +0000</pubDate>
</item>
</channel>
</rss>