<?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>DEV Community: Julien</title>
    <description>The latest articles on DEV Community by Julien (@fantomiald).</description>
    <link>https://dev.to/fantomiald</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4055914%2Fdc5e3c54-7fc9-41a4-86f1-846d71659a58.jpg</url>
      <title>DEV Community: Julien</title>
      <link>https://dev.to/fantomiald</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fantomiald"/>
    <language>en</language>
    <item>
      <title>I run all my Claude Code sessions from a pixel art office</title>
      <dc:creator>Julien</dc:creator>
      <pubDate>Wed, 11 Nov 2026 14:35:57 +0000</pubDate>
      <link>https://dev.to/fantomiald/i-run-all-my-claude-code-sessions-from-a-pixel-art-office-1mgn</link>
      <guid>https://dev.to/fantomiald/i-run-all-my-claude-code-sessions-from-a-pixel-art-office-1mgn</guid>
      <description>&lt;p&gt;Most days I have six to ten Claude Code sessions open. One is fixing a paywall, one is writing tests, one is on a landing page, one is reviewing another one's work. For a while they all lived in terminal tabs, and my real job became going through those tabs to find the one that had been waiting on a permission for twenty minutes.&lt;/p&gt;

&lt;p&gt;A terminal tab does not tell you it needs you. It just sits there.&lt;/p&gt;

&lt;p&gt;On October 14 I found &lt;a href="https://github.com/devlikemasta/bureau-des-agents" rel="noopener noreferrer"&gt;bureau-des-agents&lt;/a&gt; by devlikemasta, a small pixel art room where you watch Claude agents work. I forked it to see if I could run my real sessions in it instead of only watching them. Four weeks and 52 releases later, it is called Open Space and I have not opened a terminal tab for Claude since.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flqu2r6s34gawwsc3ckpr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flqu2r6s34gawwsc3ckpr.gif" alt="A session raises its hand, you click, answer, and it goes back to work" width="600" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The one idea
&lt;/h2&gt;

&lt;p&gt;Every session is a character at a desk. When it works, it types. When it needs you, for a permission, a question or a key, it raises its hand and lands in a "For you" list. You click, answer, and it goes back to work.&lt;/p&gt;

&lt;p&gt;That is the whole product, really. Everything else came from using it all day and hitting the next wall.&lt;/p&gt;

&lt;h2&gt;
  
  
  Under the hood
&lt;/h2&gt;

&lt;p&gt;Each session is a real &lt;code&gt;claude -p&lt;/code&gt; process talking &lt;code&gt;stream-json&lt;/code&gt; over stdin and stdout, so it runs on your own Claude Code subscription with your own config, hooks and MCP servers. The server listens on &lt;code&gt;127.0.0.1&lt;/code&gt; only and makes no outbound calls of its own. The room is drawn in code, so there is not a single image file to fetch either.&lt;/p&gt;

&lt;p&gt;The part that took longest was permissions. A headless &lt;code&gt;claude -p&lt;/code&gt; has no terminal to ask you in, and it turns out it only hands permission prompts back to you with &lt;code&gt;--permission-prompt-tool stdio&lt;/code&gt;, a flag that is not in &lt;code&gt;claude --help&lt;/code&gt;. Claude found it by running the CLI with small test prompts and reading what came back. Those outputs are saved as fixtures, and the tests replay them, so when the CLI format changes the tests are the first to say so.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the pixel art gets in the way
&lt;/h2&gt;

&lt;p&gt;I share my screen in meetings, and nobody needs to see my crew in there. &lt;code&gt;⌘ .&lt;/code&gt; swaps the room for a plain list grouped by state, with up to six conversations side by side.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwa3vzp9l7jdihuw34eqd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwa3vzp9l7jdihuw34eqd.gif" alt="Focus mode: the list on the left, conversations side by side" width="600" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sessions that step on each other
&lt;/h2&gt;

&lt;p&gt;Two sessions in the same repo will eventually edit the same file. So when you start a session in a folder that is already busy, Open Space offers to put it on its own branch in a git worktree. &lt;code&gt;.env&lt;/code&gt; and &lt;code&gt;node_modules&lt;/code&gt; are copied as APFS clones, so it starts instantly and costs no disk. When it is done, a card says "Ready to merge" with the commit count: Merge, or Open a PR.&lt;/p&gt;

&lt;p&gt;This one came straight from building Open Space inside Open Space. My own sessions kept overwriting each other's work, and after the third time I stopped fixing it by hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  The server room
&lt;/h2&gt;

&lt;p&gt;Some sessions should start without me: the security check at 7 am, the daily notes before standup, a review every time a ticket gets assigned. Triggers start a session on a cron or when something calls its webhook, and those sessions show up as robots in a server room next door. The office and the server room are linked by a portal, because of course they are.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl1juudojacaxwumb0tna.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl1juudojacaxwumb0tna.png" alt="The server room, where scheduled sessions work as robots" width="799" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each one can have a cost cap and a time cap. Past either one, the run stops and the thread says why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keys the agent never sees
&lt;/h2&gt;

&lt;p&gt;Agents keep asking for API keys, and the easy answer is to paste one into the chat, where it stays in the transcript forever. Now the agent asks for a key by name, a box opens like a question, and you paste the value there. The agent can write it to a &lt;code&gt;.env&lt;/code&gt; or run a command with it, but it only ever knows the name. The value stays in memory for 12 hours at most.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg26lllu5xreo1eghjz6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg26lllu5xreo1eghjz6g.png" alt="The agent asks for a key by name, you paste the value, it never sees it" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mods
&lt;/h2&gt;

&lt;p&gt;The last thing I added: small windows your agents build for you. You describe one ("my Claude costs this week", "today's PRs", a YouTube player), a session writes it with a kit of tested components, and it floats over the room. Each mod runs in its own origin, with no access to Open Space or its cookies.&lt;/p&gt;

&lt;h2&gt;
  
  
  The room itself
&lt;/h2&gt;

&lt;p&gt;I said I would keep this about the tool, but the room is half the reason I open it in the morning. The sky follows your clock: clouds by day, stars and a moon at night, snow at Christmas, fireworks on New Year's Eve.&lt;/p&gt;

&lt;p&gt;There are seven office themes: space shuttle, neon Tokyo, dungeon, beach bar, pirate ship, treehouse, and a hackers' cave I made last week because I wanted to work in one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzashqsi4d3c8mxfneuw2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzashqsi4d3c8mxfneuw2.gif" alt="Six of the themes" width="720" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the crew has 71 outfits and 18 pets, including a slime and a golem. All of it is drawn in code by Claude, pixel by pixel, without one image file.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Claude built it
&lt;/h2&gt;

&lt;p&gt;Almost all the code was written by Claude Code, mostly Opus, and for most of the month it was written from inside Open Space. I decided what to build, picked between mockups, and used every version myself before it shipped.&lt;/p&gt;

&lt;p&gt;The routine that held up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every bigger feature starts as an HTML mockup. I pick one before any code exists.&lt;/li&gt;
&lt;li&gt;Then a written spec and a step by step plan, both in the repo.&lt;/li&gt;
&lt;li&gt;A separate session reviews the bigger releases, without seeing the first one's reasoning.&lt;/li&gt;
&lt;li&gt;Claude bumps the version, writes the changelog and publishes the signed Mac build. The app updates itself from the GitHub release.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also stopped being only mine. Quentin ported it to Windows, Mouhrad brought the triggers and the Telegram bot, and GC and JB keep sending PRs I would not have thought of.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is now
&lt;/h2&gt;

&lt;p&gt;v1.32, MIT, Mac and Windows, 72 stars. I use it every day, for everything, and that is the main test it passes. It is still rough in places.&lt;/p&gt;

&lt;p&gt;If you try it, the feedback I want most: what made you go back to a terminal tab, and what you had to work out on your own in the first five minutes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Fantomiald/open-space" rel="noopener noreferrer"&gt;github.com/Fantomiald/open-space&lt;/a&gt;, with the Mac and Windows builds under Releases&lt;/li&gt;
&lt;li&gt;or clone it and run &lt;code&gt;npm start&lt;/code&gt; (Node 22.18+) to open it in your browser&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You need Claude Code installed and logged in.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Open Space started as a fork of &lt;a href="https://github.com/devlikemasta/bureau-des-agents" rel="noopener noreferrer"&gt;devlikemasta/bureau-des-agents&lt;/a&gt;. Not affiliated with Anthropic.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>1,756 hand drawn icons, and nobody drew them</title>
      <dc:creator>Julien</dc:creator>
      <pubDate>Fri, 31 Jul 2026 05:05:25 +0000</pubDate>
      <link>https://dev.to/fantomiald/1756-hand-drawn-icons-and-nobody-drew-them-1cpi</link>
      <guid>https://dev.to/fantomiald/1756-hand-drawn-icons-and-nobody-drew-them-1cpi</guid>
      <description>&lt;p&gt;For a while my routine on side projects was this: find one sketchy icon somewhere, download the SVG, rename it, drop it in &lt;code&gt;assets&lt;/code&gt;, then fix its stroke width because it never matched anything else I had. Next project, same thing. The hand drawn sets I could find were small and the glyph I wanted was never in them.&lt;/p&gt;

&lt;p&gt;I did that enough times to start wondering why I was doing it by hand at all. The look comes down to a wobble in the line, and a wobble is arithmetic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://roughjs.com" rel="noopener noreferrer"&gt;Rough.js&lt;/a&gt; had worked that out years ago. It draws hand drawn shapes in the browser, and reading how it does it is what stopped me treating the effect as something you need an illustrator for. Bow the straight lines a little, move the endpoints around, and an eye reads that as a hand.&lt;/p&gt;

&lt;p&gt;The other half was already solved too. I use &lt;a href="https://lucide.dev" rel="noopener noreferrer"&gt;Lucide&lt;/a&gt; in everything I build. 1,756 glyphs on a 24 unit grid with a 2 pixel stroke, and somebody has already had the argument about what a "database backup" icon should look like. That argument is the hard part of building an icon set, and it was done.&lt;/p&gt;

&lt;p&gt;So the plan was to take geometry that already works and add the hand with code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The generator
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@sketchyicons&lt;/code&gt; is what came out of that. It reads Lucide's paths, bows every straight run into a quadratic with the control point pushed off the chord, drifts every coordinate by a fraction of a unit, and takes the random sequence for that drift from the icon's own name.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;arrow-right&lt;/code&gt; in Lucide is &lt;code&gt;M5 12h14&lt;/code&gt;. A horizontal line, 14 units long. After the generator it is &lt;code&gt;M5 11.99Q12 11.56 18.81 11.93&lt;/code&gt;, a curve whose control point sits four tenths of a unit off the chord. There are 7,027 paths in the catalogue and every one of them goes through that.&lt;/p&gt;

&lt;p&gt;Because the sequence comes from the name and not from a clock, two runs of the generator write byte identical files, and there is a test that fails if they ever stop doing that. An icon set that redraws itself on every build would put noise in every diff I ever open, so it was not going to ship that way.&lt;/p&gt;

&lt;p&gt;How much hand a coordinate gets depends on where it sits. Short runs move less than long ones. If a subpath is made of straight lines only, a cross or a chevron, it gets held closer to the ruler, and skipping that gives you a &lt;code&gt;circle-plus&lt;/code&gt; whose plus looks broken rather than drawn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Actually using it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @sketchyicons/react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Star&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@sketchyicons/react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;House&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Star&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#2B2521"&lt;/span&gt; &lt;span class="na"&gt;strokeWidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mf"&gt;1.75&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The props are Lucide's, &lt;code&gt;size&lt;/code&gt; &lt;code&gt;color&lt;/code&gt; &lt;code&gt;strokeWidth&lt;/code&gt; &lt;code&gt;absoluteStrokeWidth&lt;/code&gt; &lt;code&gt;fill&lt;/code&gt;, so if Lucide is already in your project the migration is the import line. The 247 names Lucide has renamed over the years are exported next to the current ones, so &lt;code&gt;Home&lt;/code&gt;, &lt;code&gt;HelpCircle&lt;/code&gt; and &lt;code&gt;MoreHorizontal&lt;/code&gt; still resolve and you do not have to work out which ones moved.&lt;/p&gt;

&lt;p&gt;Ten packages went out together: React, React Native, Vue, Preact, Solid, Svelte, Angular, a plain DOM build, the geometry on its own as JSON, and the SVG files plus a sprite for anything that is not JavaScript. One icon costs between 250 bytes and 1.18 kB depending on the target, minified and brotlied. Nothing carries a runtime dependency except Angular, which pulls tslib like every Angular library does.&lt;/p&gt;

&lt;p&gt;Svelte and Angular get a single component that takes the icon as data. Both of them compile a component per file in your build, so shipping 1,756 files would mean 1,756 compilations in a project that imports three of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is now
&lt;/h2&gt;

&lt;p&gt;I use it in my own projects and that is the entire track record. It sits at 0.5.0, MIT.&lt;/p&gt;

&lt;p&gt;If you do try it, the feedback worth having is whether the wobble is too much or not enough, and whether it survives at 15 pixels inside a real button. That size is where a bowed stroke either holds or turns to mud, and it is the one I keep going back to. Also worth telling me: which target is missing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sketchyicons.com" rel="noopener noreferrer"&gt;sketchyicons.com&lt;/a&gt;, searchable, a page per icon&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Fantomiald/sketchyicons" rel="noopener noreferrer"&gt;github.com/Fantomiald/sketchyicons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/org/sketchyicons" rel="noopener noreferrer"&gt;npmjs.com/org/sketchyicons&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Geometry derived from Lucide 1.27.0, ISC, copyright Lucide Icons and Contributors. Not affiliated with Lucide, not endorsed by them.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
