<?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: Rudi K. 🧠</title>
    <description>The latest articles on DEV Community by Rudi K. 🧠 (@lofifounder).</description>
    <link>https://dev.to/lofifounder</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%2F3297599%2F970ddbfe-e89d-4175-af4b-8888d088ed38.jpg</url>
      <title>DEV Community: Rudi K. 🧠</title>
      <link>https://dev.to/lofifounder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lofifounder"/>
    <language>en</language>
    <item>
      <title>Building a lightweight, offline screenshot beautifier in Rust</title>
      <dc:creator>Rudi K. 🧠</dc:creator>
      <pubDate>Tue, 07 Apr 2026 08:13:19 +0000</pubDate>
      <link>https://dev.to/lofifounder/building-a-lightweight-offline-screenshot-beautifier-in-rust-4fac</link>
      <guid>https://dev.to/lofifounder/building-a-lightweight-offline-screenshot-beautifier-in-rust-4fac</guid>
      <description>&lt;p&gt;If you're a developer like me who genuinely enjoys working on a PC, you might relate to a specific feeling. Even though Windows itself has really grown into its polish over the years, a lot of the third-party utility apps haven't quite caught up. We have tools that are incredibly powerful, but they often focus purely on function and miss out on that clean, modern aesthetic you'd expect in 2026.&lt;/p&gt;

&lt;p&gt;Over the past year, I built two &lt;a href="https://github.com/rudi-q/leed_pdf_viewer" rel="noopener noreferrer"&gt;open-source&lt;/a&gt; projects, &lt;em&gt;&lt;a href="https://leedpdf.com" rel="noopener noreferrer"&gt;LeedPDF&lt;/a&gt;&lt;/em&gt; and &lt;em&gt;&lt;a href="https://glucose.media" rel="noopener noreferrer"&gt;Glucose Video Player&lt;/a&gt;&lt;/em&gt;. They ended up getting way more love than I ever expected, especially from the PC crowd. That response validated something I've felt for a long time: a lot of us like being on Windows, but we are starved for high-quality, UX-focused desktop apps.&lt;/p&gt;

&lt;p&gt;The acceptance of those utility tools (which I originally just built for myself) got me thinking about other areas of my daily workflow that were overdue for an upgrade.&lt;/p&gt;

&lt;p&gt;Sharing screenshots was one of those things for me. From my college days until now, whether I needed to add a screenshot to a presentation, share it on Slack with the team, post on social media, or drop it into documentation. I just never liked looking at raw, unpolished screenshots. But I was also tired of having to open up Figma or use clunky software just to add a nice background and some basic padding.&lt;/p&gt;

&lt;p&gt;That’s why I started building &lt;a href="https://doublshot.com" rel="noopener noreferrer"&gt;DoublShot&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is DoublShot?
&lt;/h3&gt;

&lt;p&gt;It’s a minimalist tool that sits in your tray and replaces your default snipping workflow. You take a screenshot, and it automatically makes it look polished, cleaner, and presentation-ready by adding perfect padding, a drop shadow, and a complementary background gradient that matches the colors in your image.&lt;/p&gt;

&lt;p&gt;In a nutshell, I tried my best to keep it as simple, minimalist, and UX-friendly as I possibly could.&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.amazonaws.com%2Fuploads%2Farticles%2Ffrr3vu8k2afygpkdynlt.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.amazonaws.com%2Fuploads%2Farticles%2Ffrr3vu8k2afygpkdynlt.png" alt="DoublShot features" width="800" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Tech &amp;amp; The Philosophy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I built this with a few strict rules:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. It has to be incredibly fast.&lt;/strong&gt;&lt;br&gt;
I wrote the core of DoublShot in Rust. This means the memory footprint is tiny and the performance is unmatched. There's near-zero latency from the moment you hit the shortcut to the moment the styled image hits your clipboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It must be completely private.&lt;/strong&gt;&lt;br&gt;
No data leaves your PC. Period. It is an offline-first, local binary. I hate tools that require you to upload your clipboard to the cloud just to add a background.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. No SaaS / Subscription bloat.&lt;/strong&gt;&lt;br&gt;
I am exhausted by subscription fatigue. DoublShot has a generous free version, but even the premium version is not a SaaS. You buy a license, and you own the software for life. It's yours to keep, and you'll still receive updates.&lt;/p&gt;

&lt;p&gt;I'd love your feedback&lt;/p&gt;

&lt;p&gt;Building this has been a really fun dive into desktop app development and UX design.&lt;/p&gt;

&lt;p&gt;I’d love to have the dev.to community try it out. If you're on Windows and want to upgrade how you share visual updates, you can grab it for free here:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://doublshot.com" rel="noopener noreferrer"&gt;doublshot.com&lt;/a&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fmth3s1n9k31l1x65qhxo.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.amazonaws.com%2Fuploads%2Farticles%2Fmth3s1n9k31l1x65qhxo.png" alt="DoublShot" width="666" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please share any valuable feedback, bug reports, or feature requests! Your input on my past projects helped shape them immensely, and I'm hoping to do the same here to refine DoublShot for everyone.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>windows</category>
      <category>productivity</category>
      <category>uxdesign</category>
    </item>
    <item>
      <title>Building A Keyboard-First Video Player with Svelte &amp; Rust</title>
      <dc:creator>Rudi K. 🧠</dc:creator>
      <pubDate>Fri, 24 Oct 2025 04:33:06 +0000</pubDate>
      <link>https://dev.to/lofifounder/building-a-keyboard-first-video-player-with-svelte-rust-dk7</link>
      <guid>https://dev.to/lofifounder/building-a-keyboard-first-video-player-with-svelte-rust-dk7</guid>
      <description>&lt;p&gt;Until about five months ago, I didn’t even have a single public repo on GitHub.&lt;br&gt;
Every project I’d built was closed-source, mostly private tools or experimental stuff that never saw the light of day.&lt;/p&gt;

&lt;p&gt;But at some point, I realized how much of what I use every day exists because someone decided to make their work open.&lt;br&gt;
So I figured, why not give back?&lt;/p&gt;

&lt;p&gt;That led to &lt;a href="https://github.com/rudi-q/cristalyse" rel="noopener noreferrer"&gt;Cristalyse&lt;/a&gt; and then &lt;a href="https://github.com/rudi-q/leed_pdf_viewer" rel="noopener noreferrer"&gt;LeedPDF&lt;/a&gt;, which, funnily enough, ended up being my fastest-growing app ever.&lt;/p&gt;

&lt;p&gt;LeedPDF crossed 100 GitHub stars faster than I ever expected, and that tiny milestone made me want to keep going.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rudi-q" rel="noopener noreferrer"&gt;
        rudi-q
      &lt;/a&gt; / &lt;a href="https://github.com/rudi-q/leed_pdf_viewer" rel="noopener noreferrer"&gt;
        leed_pdf_viewer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Open-source PDF annotation and drawing tool built for privacy. Sketch and annotate PDFs with natural pen-like precision, drawing tablet support. SvelteKit + Tauri.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/rudi-q/leed_pdf_viewer/static/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frudi-q%2Fleed_pdf_viewer%2Fstatic%2Flogo.png" alt="LeedPDF Logo" width="160" height="160"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;LeedPDF - Free PDF Annotation Tool&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Add drawings and notes to any PDF.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Works with mouse, touch, or stylus - completely free and private.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="https://www.gnu.org/licenses/agpl-3.0" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8864ac9cd55989c144d1fe4ee4b950248f137882a313d77b4e4b16773a5498d7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4147504c253230332e302d3837413936422e737667" alt="License: AGPL-3.0"&gt;&lt;/a&gt;
&lt;a href="https://buy.polar.sh/polar_cl_tPmQ3d72uYwrYvzzIUM4R7cku7hg2kmEQqruI1its5c" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ae509ba2ee2fa4b9861c5b93a74f9c4a330d3353716df44df736a0965dc7924e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6d6d65726369616c2532304c6963656e73652d417661696c61626c652d3837413936422e737667" alt="Commercial License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/leed_pdf_viewer#web-app-agpl" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c96f38dc1d8702008d09dc544805f8e926a482147ef5471dabb99c4eb5237f55/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f467265652d5765622532304170702d3837413936422e737667" alt="Free for Personal Use on Web"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/leed_pdf_viewer/stargazers" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/63e0e95f939d0283e6645c454772dfa109604d985f81efde673209b879c405ef/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f727564692d712f6c6565645f7064665f7669657765723f636f6c6f723d383741393642267374796c653d666c6174266c6f676f3d676974687562" alt="GitHub Stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/leed_pdf_viewer/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/53a02b91f69f5ea22a10e79ec7e7df07f9c517dfcafc5838b2c2035f7f2da2f0/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f727564692d712f6c6565645f7064665f7669657765722f746f74616c3f6c6162656c3d446f776e6c6f616473266c6f676f3d67697468756226636f6c6f723d383741393642" alt="Downloads"&gt;&lt;/a&gt;
&lt;a href="https://www.w3.org/WAI/WCAG2AAA-Conformance" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/af13df82bbd406f340b90e810933a1aaf2e596959e18a29a9c09aed9f53414ef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f574341472532304141412d436f6d706c69616e742d3837413936423f7374796c653d666c6174266c6f676f3d6163636573736962696c697479616c74266c6f676f436f6c6f723d7768697465" alt="WCAG AAA Compliant"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://kit.svelte.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bbb59172a14b8fd9aa9753bf59874d4b24b5484004753f84f70fe36594c0da78/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5376656c74654b69742d4646334530303f7374796c653d666c6174266c6f676f3d7376656c7465266c6f676f436f6c6f723d7768697465" alt="SvelteKit"&gt;&lt;/a&gt;
&lt;a href="https://www.typescriptlang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3414bd6550fc1cbc705d8b6f6a0703edd60842f3e422a97853b052f8b4ff13bf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f547970655363726970742d3030374143433f7374796c653d666c6174266c6f676f3d74797065736372697074266c6f676f436f6c6f723d7768697465" alt="TypeScript"&gt;&lt;/a&gt;
&lt;a href="https://tauri.app/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3a37b78df4166b59d8e039c261cb48ccd78b4804eb4c33c01affc1d7d1471a6a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54617572692d3234433844383f7374796c653d666c6174266c6f676f3d7461757269266c6f676f436f6c6f723d7768697465" alt="Tauri"&gt;&lt;/a&gt;
&lt;a href="https://mozilla.github.io/pdf.js/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9396c2a0f0db22ffb38e68b1730685ad77f1af524ae10d1799a66a4bc6a5c0ef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5044462e6a732d3030303030303f7374796c653d666c6174266c6f676f3d6d6f7a696c6c61266c6f676f436f6c6f723d7768697465" alt="PDF.js"&gt;&lt;/a&gt;
&lt;a href="https://api.search.brave.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1739154a7273bfd45341848945e4cd47b6d30f79f817469974ed57e7b2cdf089/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f42726176652532305365617263682d4642353432423f7374796c653d666c6174266c6f676f3d6272617665266c6f676f436f6c6f723d7768697465" alt="Brave Search API"&gt;&lt;/a&gt;
&lt;a href="https://tailwindcss.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6b9d37def8afc480d0b20fc34c6717b709a58b4262fbf52e4edb32b5b40d83c8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5461696c77696e645f4353532d3036423644343f7374796c653d666c6174266c6f676f3d7461696c77696e64637373266c6f676f436f6c6f723d7768697465" alt="Tailwind CSS"&gt;&lt;/a&gt;
&lt;a href="https://vitejs.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/19bbe6aeb3a1d66722d8359bda2903e7d5c69e234fa5b43adeda5dfe93fbe512/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566974652d3634364346463f7374796c653d666c6174266c6f676f3d76697465266c6f676f436f6c6f723d7768697465" alt="Vite"&gt;&lt;/a&gt;
&lt;a href="https://coderabbit.ai/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/84cf4d6d96afbc870ee06cac1f447b22070497616a66e721b733cdd22515f4d5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f64655261626269742d4646353730413f7374796c653d666c6174266c6f676f3d636f6465726162626974266c6f676f436f6c6f723d7768697465" alt="CodeRabbit"&gt;&lt;/a&gt;
&lt;a href="https://appwrite.io/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ff06d4540d47a0468dff1e8c72d80c36a8369ee974d251d2a839d7de744d2baa/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f41707077726974652d4630324536353f7374796c653d666c6174266c6f676f3d6170707772697465266c6f676f436f6c6f723d7768697465" alt="Appwrite"&gt;&lt;/a&gt;
&lt;a href="https://vercel.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fe48bc13928ab2395c1293aea537972cd0369cf6a6db11f2f242cb5565711557/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f56657263656c2d3030303030303f7374796c653d666c6174266c6f676f3d76657263656c266c6f676f436f6c6f723d7768697465" alt="Vercel"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;A modern, open-source PDF annotation tool that runs entirely in your browser&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Transform any PDF into an interactive canvas. Draw, annotate, and collaborate without uploading your documents to external servers.&lt;/p&gt;
&lt;div&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/rudi-q/leed_pdf_viewer/static/screenshot.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frudi-q%2Fleed_pdf_viewer%2Fstatic%2Fscreenshot.png" alt="LeedPDF in action - annotating a Y Combinator fundraising guide with highlights, comments, and drawings" width="800"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://leed.my" rel="nofollow noopener noreferrer"&gt;&lt;strong&gt;Try it now →&lt;/strong&gt;&lt;/a&gt; | &lt;a href="https://github.com/rudi-q/leed_pdf_viewer/issues" rel="noopener noreferrer"&gt;&lt;strong&gt;Report Issues&lt;/strong&gt;&lt;/a&gt; | &lt;a href="https://github.com/rudi-q/leed_pdf_viewer/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;&lt;strong&gt;Contribute&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🔍 &lt;strong&gt;PDF Search &amp;amp; Discovery&lt;/strong&gt;
&lt;/h3&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web-wide PDF search&lt;/strong&gt; powered by Brave Search API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct PDF opening&lt;/strong&gt; from search results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart filtering&lt;/strong&gt; for PDF documents only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pagination&lt;/strong&gt; through search results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time search&lt;/strong&gt; with instant results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Setup guide&lt;/strong&gt;: See &lt;a href="https://github.com/rudi-q/leed_pdf_viewer/docs/SEARCH_FEATURE.md" rel="noopener noreferrer"&gt;docs/SEARCH_FEATURE.md&lt;/a&gt; for configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🎨 &lt;strong&gt;Drawing &amp;amp; Annotation&lt;/strong&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Freehand drawing&lt;/strong&gt; with customizable pencil and highlighter tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shape tools&lt;/strong&gt; including rectangles, circles, arrows, and stars&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text annotations&lt;/strong&gt; with inline editing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sticky notes&lt;/strong&gt; for quick comments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart eraser&lt;/strong&gt; that removes intersecting elements&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;📱 &lt;strong&gt;Universal Access&lt;/strong&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Works on &lt;strong&gt;any device&lt;/strong&gt; -…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rudi-q/leed_pdf_viewer" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;I’ve always loved Flutter, but working with Svelte on LeedPDF genuinely made me fall in love with it, it’s just so reactive, elegant, and fun to build with. And pairing that with Rust, well… Rust makes everything snappy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Built Glucose
&lt;/h2&gt;

&lt;p&gt;As someone who’s used VLC for years, I’ve always respected how powerful it is, it’s the Swiss Army knife of video players.&lt;br&gt;
But let’s be honest: it doesn’t exactly look like something from 2025.&lt;/p&gt;

&lt;p&gt;It’s cluttered, it’s got buttons for things I never touch, and it feels… old.&lt;br&gt;
I wanted a video player that’s private, open source, and brutally minimal, something that just plays my videos and gets out of the way.&lt;/p&gt;

&lt;p&gt;That’s how Glucose started.&lt;br&gt;
A zero-UI video player, simple, focused, and lightweight.&lt;br&gt;
The installer? Just 4MB.&lt;/p&gt;

&lt;p&gt;Rust helped a lot with performance, and Svelte handled the rest with elegance.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Stack
&lt;/h2&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.amazonaws.com%2Fuploads%2Farticles%2Febin90yq0vakowjrlz2c.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.amazonaws.com%2Fuploads%2Farticles%2Febin90yq0vakowjrlz2c.png" alt="SvelteKit, Rust, TypeScript"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SvelteKit + Rust + Tauri became my go-to stack for Glucose.&lt;/p&gt;

&lt;p&gt;SvelteKit for the UI, reactive, clean, and a joy to build with.&lt;/p&gt;

&lt;p&gt;Rust for performance-critical tasks and local file handling.&lt;/p&gt;

&lt;p&gt;Tauri for packaging everything into a native desktop experience that stays tiny.&lt;/p&gt;

&lt;p&gt;Electron would’ve made the build 10x heavier, and Flutter (as much as I love it) wasn’t the right fit for a desktop-first app.&lt;/p&gt;

&lt;p&gt;Svelte + Rust feels underrated, especially for apps that need both high reactivity and low-level performance. It’s honestly one of the smoothest pairings I’ve worked with.&lt;/p&gt;
&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

&lt;p&gt;Here’s the basic flow:&lt;/p&gt;

&lt;p&gt;The frontend (SvelteKit) handles the player UI and keyboard interactions.&lt;/p&gt;

&lt;p&gt;The backend (Rust via Tauri) deals with video decoding, file access, and media control.&lt;/p&gt;

&lt;p&gt;Communication between them happens through Tauri’s command bridge.&lt;/p&gt;

&lt;p&gt;It’s clean, fast, and predictable.&lt;br&gt;
Rust takes care of the heavy lifting, while Svelte keeps the experience buttery smooth.&lt;/p&gt;
&lt;h2&gt;
  
  
  Keyboard-First Experience
&lt;/h2&gt;

&lt;p&gt;Glucose is all about low cognitive load.&lt;br&gt;
I designed it so you never have to touch your mouse, not even once.&lt;br&gt;
You can:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Press Space or K to play/pause
- ← and → to seek backward/forward
- K to toggle playback speed
- Jump to percentage (0% - 90%): 0 - 9
- / to open a command overlay for quick actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once you get used to it, you realize how much friction you were tolerating in other players.&lt;/p&gt;
&lt;h2&gt;
  
  
  Offline-First and Fast
&lt;/h2&gt;

&lt;p&gt;No telemetry. No tracking. No analytics.&lt;br&gt;
Everything Glucose does stays on your device.&lt;/p&gt;

&lt;p&gt;It runs entirely offline and launches almost instantly.&lt;br&gt;
That’s the beauty of combining Rust’s efficiency with Svelte’s reactivity, the whole app just feels effortless.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rudi-q" rel="noopener noreferrer"&gt;
        rudi-q
      &lt;/a&gt; / &lt;a href="https://github.com/rudi-q/glucose_media_player" rel="noopener noreferrer"&gt;
        glucose_media_player
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Ultra-lightweight, video player for Windows with AI powered subtitle generation. Tauri + Svelte
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
  &lt;a href="https://glucose.media" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frudi-q%2Fglucose_media_player%2Fstatic%2Flogo-dark.svg" alt="Glucose Media Player" width="400"&gt;&lt;/a&gt;
&lt;p&gt;&lt;em&gt;A Sleek &amp;amp; Lightweight VLC Alternative with On-Device AI Subtitle&lt;br&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1e3d5bd735bcda2906d772be295a7f44fe3570fb5a61ce46f9b95e519c62d9d8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d504c25323076322e302d3161316131613f7374796c653d666f722d7468652d6261646765266c6f676f3d6f70656e736f75726365696e6974696174697665266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d306130613061" alt="License: MPL"&gt;&lt;/a&gt;
&lt;a href="https://tauri.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6170013c94c95a38d5a79e58d3a5f73a5b177a2ee2a37ec06dd3031e49efaef2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4275696c74253230776974682d54617572692d3161316131613f7374796c653d666f722d7468652d6261646765266c6f676f3d7461757269266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d306130613061" alt="Built with Tauri"&gt;&lt;/a&gt;
&lt;a href="https://svelte.dev" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/38a178970fe24e156be5b7ee9922b5b145b70b8a1cf3f91eb60fd16cebe587a4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f46726f6e74656e642d5376656c74652d3161316131613f7374796c653d666f722d7468652d6261646765266c6f676f3d7376656c7465266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d306130613061" alt="Svelte"&gt;&lt;/a&gt;
&lt;a href="https://rust-lang.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/685b32c8729e90128376daa8e620b5c3d3ccdb761a29dd0b584f2455faf09191/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4261636b656e642d527573742d3161316131613f7374796c653d666f722d7468652d6261646765266c6f676f3d72757374266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d306130613061" alt="Rust"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/rudi-q/glucose_media_player/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bdf01f11fc739305ebd2aad084bff798a54b1cf0527c624022b01a000b091a4d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f727564692d712f676c75636f73655f6d656469615f706c617965723f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d30613061306126636f6c6f723d316131613161266c6162656c3d56657273696f6e" alt="Version"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/glucose_media_player/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/917e5923afd20d8339f6e18d3143829551b4650ab3f34004349a6663968a40ce/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f727564692d712f676c75636f73655f6d656469615f706c617965722f746f74616c3f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d30613061306126636f6c6f723d316131613161" alt="Downloads"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/glucose_media_player/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/69301e30f04b85c5756010a51024c296b2d4f7f7c042435b6086f93e3ea626de/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f506c6174666f726d2d57696e646f77732532302d3161316131613f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d306130613061" alt="Platform"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🎬 Cinematic Mode&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;Enjoy your media with a beautifully blurred background and centered content for truly immersive viewing.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🖼️ Universal Media Support&lt;/h3&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Videos&lt;/strong&gt;: MP4, MKV, AVI, MOV, WebM, WMV, FLV, M4V&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subtitles&lt;/strong&gt;: SRT, VTT, ASS, SSA, SUB&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🎯 Minimal by Design&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;No clutter, no distractions. Just your content and elegant controls that appear when you need them.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;⚡ Blazingly Fast&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;Built with Rust and Tauri for native performance with a tiny footprint.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🎮 Keyboard-First&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;Complete keyboard navigation for power users who value efficiency.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;📂 Smart Gallery&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;Automatically scans and displays your recent videos in a beautiful grid layout.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🎨 Modern Interface&lt;/h3&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Frameless, transparent window design&lt;/li&gt;
&lt;li&gt;Smooth animations and transitions&lt;/li&gt;
&lt;li&gt;Audio output device selection&lt;/li&gt;
&lt;li&gt;Volume control with visual feedback&lt;/li&gt;
&lt;li&gt;Timeline scrubbing with video preview&lt;/li&gt;
&lt;li&gt;Fullscreen and cinematic viewing modes&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📥 Installation&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Pre-built Binaries&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;Download the latest release…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rudi-q/glucose_media_player" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;





&lt;p&gt;Everything’s open-source under MPL.&lt;br&gt;
👉 &lt;a href="https://github.com/rudi-q/glucose_media_player" rel="noopener noreferrer"&gt;github.com/rudi-q/glucose_media_player&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Five months ago, I didn’t even know what it felt like to share my work openly.&lt;br&gt;
Now, I can’t imagine not doing it.&lt;/p&gt;

&lt;p&gt;Building Glucose reminded me that open source doesn’t have to be massive, it just has to be honest.&lt;br&gt;
Sometimes, it’s about building the small, quiet things that make your day smoother.&lt;/p&gt;

&lt;p&gt;Glucose is one of those things for me. &lt;br&gt;
Try it, it's FREE :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://glucose.media" rel="noopener noreferrer"&gt;glucose.media&lt;/a&gt;&lt;/p&gt;




</description>
      <category>svelte</category>
      <category>rust</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cristalyse - The Only Flutter Chart Package with MCP Support Built In</title>
      <dc:creator>Rudi K. 🧠</dc:creator>
      <pubDate>Mon, 08 Sep 2025 14:02:39 +0000</pubDate>
      <link>https://dev.to/lofifounder/cristalyse-the-only-flutter-chart-package-with-mcp-support-built-in-375p</link>
      <guid>https://dev.to/lofifounder/cristalyse-the-only-flutter-chart-package-with-mcp-support-built-in-375p</guid>
      <description>&lt;p&gt;&lt;em&gt;How Cristalyse is pioneering AI-assisted chart development in Flutter&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;As Flutter developers, we've all been there: you're deep in the flow, building out your data visualization, when you hit a wall. "How do I add dual Y-axes again?" or "What was the syntax for that bubble chart mapping?" You alt-tab to docs, lose your train of thought, and your productivity takes a hit.&lt;/p&gt;

&lt;p&gt;What if your AI coding assistant could answer these questions directly in your IDE, with complete knowledge of your chart library's API? That's exactly what we've built with &lt;strong&gt;Cristalyse v1.6.1&lt;/strong&gt; - the first Flutter chart package with built-in Model Context Protocol (MCP) support.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes This Groundbreaking?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MCP isn't just another feature&lt;/strong&gt; - it's a fundamental shift in how we think about developer tooling. Instead of treating documentation as a separate resource, MCP creates a direct bridge between your coding environment and the knowledge base of your tools.&lt;/p&gt;

&lt;p&gt;For Flutter chart development, this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero context switching&lt;/strong&gt; between IDE and documentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant access&lt;/strong&gt; to working code examples&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time guidance&lt;/strong&gt; on complex APIs like grammar of graphics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contextual help&lt;/strong&gt; that understands what you're trying to build&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Technical Foundation: Why Charts Need This Most
&lt;/h2&gt;

&lt;p&gt;Building charts isn't like implementing typical Flutter widgets. Chart libraries, especially ones implementing grammar of graphics (like Cristalyse), have inherently complex APIs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This is just a simple scatter plot, but look at the API surface:&lt;/span&gt;
&lt;span class="n"&gt;CristalyseChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salesData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x:&lt;/span&gt; &lt;span class="s"&gt;'quarter'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;y:&lt;/span&gt; &lt;span class="s"&gt;'revenue'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="s"&gt;'region'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;size:&lt;/span&gt; &lt;span class="s"&gt;'growth'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;geomPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;size:&lt;/span&gt; &lt;span class="mf"&gt;8.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;alpha:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;shape:&lt;/span&gt; &lt;span class="n"&gt;PointShape&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleXContinuous&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;domain:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleYContinuous&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;format:&lt;/span&gt; &lt;span class="n"&gt;NumberFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleColorDiscrete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;palette:&lt;/span&gt; &lt;span class="n"&gt;CustomPalette&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;business&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleSizeLinear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;range:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChartTheme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;professional&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;duration:&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;milliseconds:&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;interaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;tooltip:&lt;/span&gt; &lt;span class="n"&gt;TooltipConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;mainAxisSize:&lt;/span&gt; &lt;span class="n"&gt;MainAxisSize&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Q&lt;/span&gt;&lt;span class="si"&gt;${point.getValue('quarter')}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Revenue: &lt;/span&gt;&lt;span class="si"&gt;${currencyFormat.format(point.getValue('revenue'))}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Region: &lt;/span&gt;&lt;span class="si"&gt;${point.getValue('region')}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;That's a lot of moving parts.&lt;/strong&gt; And this is still a relatively simple example. When you factor in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple geometry layers&lt;/li&gt;
&lt;li&gt;Custom scales and transformations
&lt;/li&gt;
&lt;li&gt;Complex interaction handling&lt;/li&gt;
&lt;li&gt;Animation coordination&lt;/li&gt;
&lt;li&gt;Theme customization&lt;/li&gt;
&lt;li&gt;Data preprocessing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cognitive load becomes substantial. This is where AI assistance becomes genuinely valuable, not just convenient.&lt;/p&gt;

&lt;h2&gt;
  
  
  How MCP Works Under the Hood
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol creates a standardized way for AI applications to connect to external knowledge sources. Here's the technical flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph LR
    A[Your IDE] --&amp;gt; B[AI Assistant]
    B --&amp;gt; C[MCP Client]
    C --&amp;gt; D[HTTPS Request]
    D --&amp;gt; E[Cristalyse MCP Server]
    E --&amp;gt; F[Documentation DB]
    F --&amp;gt; E
    E --&amp;gt; D
    D --&amp;gt; C
    C --&amp;gt; B
    B --&amp;gt; A
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you ask your AI assistant about Cristalyse:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Query Processing&lt;/strong&gt;: Your question gets sent to the AI assistant&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Resolution&lt;/strong&gt;: The assistant identifies this as a Cristalyse-related query&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server Connection&lt;/strong&gt;: Makes a secure HTTPS request to &lt;code&gt;https://docs.cristalyse.com/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Retrieval&lt;/strong&gt;: Our MCP server returns relevant documentation, examples, and API references&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response Generation&lt;/strong&gt;: The AI assistant combines this knowledge with its understanding to give you a complete answer&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setting Up MCP: The Developer Experience
&lt;/h2&gt;

&lt;p&gt;The setup is intentionally frictionless. For most AI coding assistants, it's just adding one line to your MCP configuration:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cursor/Windsurf/Warp:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cristalyse_docs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://docs.cristalyse.com/mcp"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Claude Code CLI:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http cristalyse_docs https://docs.cristalyse.com/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Claude Web/Desktop:&lt;/strong&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fu7387i3omuwd54qc6byi.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.amazonaws.com%2Fuploads%2Farticles%2Fu7387i3omuwd54qc6byi.png" alt="Adding Cristalyse MCP to Claude" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add a custom connector with URL: &lt;code&gt;https://docs.cristalyse.com/mcp&lt;/code&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fb29jifd8pm6h2kizxjnz.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.amazonaws.com%2Fuploads%2Farticles%2Fb29jifd8pm6h2kizxjnz.png" alt="Cristalyse MCP added to Claude" width="800" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it. No API keys, no authentication complexity, no additional dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Impact: Before vs After
&lt;/h2&gt;

&lt;p&gt;Let me show you the difference with a concrete example. Say you want to build a dual Y-axis chart comparing revenue and customer count over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before MCP:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remember that Cristalyse supports dual Y-axis (if you remember at all)&lt;/li&gt;
&lt;li&gt;Open documentation in browser&lt;/li&gt;
&lt;li&gt;Search for "dual Y-axis" or "secondary axis"&lt;/li&gt;
&lt;li&gt;Find the relevant API methods&lt;/li&gt;
&lt;li&gt;Look for code examples&lt;/li&gt;
&lt;li&gt;Copy/paste and adapt to your data&lt;/li&gt;
&lt;li&gt;Debug inevitable syntax issues&lt;/li&gt;
&lt;li&gt;Repeat for styling, interactions, etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;With MCP:&lt;/strong&gt;&lt;br&gt;
Simply ask in your IDE: &lt;em&gt;"Show me how to create a dual Y-axis chart with Cristalyse where left axis shows revenue and right axis shows customer count, both animated"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your AI assistant responds immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;CristalyseChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;businessData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x:&lt;/span&gt; &lt;span class="s"&gt;'month'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;y:&lt;/span&gt; &lt;span class="s"&gt;'revenue'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;y2:&lt;/span&gt; &lt;span class="s"&gt;'customers'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;geomLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;geomLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;yAxis:&lt;/span&gt; &lt;span class="n"&gt;YAxis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;green&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleYContinuous&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;format:&lt;/span&gt; &lt;span class="n"&gt;NumberFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s"&gt;"'Revenue (&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s"&gt;)',"&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleY2Continuous&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;format:&lt;/span&gt; &lt;span class="n"&gt;NumberFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;decimalPattern&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s"&gt;"'Customer Count',"&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChartTheme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;business&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;duration:&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;milliseconds:&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI can even explain the key concepts: "The &lt;code&gt;y2&lt;/code&gt; mapping creates a secondary Y-axis, and &lt;code&gt;yAxis: YAxis.secondary&lt;/code&gt; tells the second line geometry to use that axis..."&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Grammar of Graphics + AI is Powerful
&lt;/h2&gt;

&lt;p&gt;Cristalyse implements the grammar of graphics paradigm (think ggplot2 for Flutter). This creates an interesting synergy with AI assistance:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Composable APIs benefit from guided assembly.&lt;/strong&gt; Grammar of graphics is all about layering components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data + Mappings + Geometries + Scales + Themes = Chart&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI can help you navigate these layers intelligently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Ask: "I have sales data with categories, how do I make a stacked bar chart?"&lt;/span&gt;
&lt;span class="c1"&gt;// AI understands you need:&lt;/span&gt;

&lt;span class="n"&gt;CristalyseChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salesData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x:&lt;/span&gt; &lt;span class="s"&gt;'quarter'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;y:&lt;/span&gt; &lt;span class="s"&gt;'amount'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;fill:&lt;/span&gt; &lt;span class="s"&gt;'category'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;// ^ AI knows 'fill' creates the stacking&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;geomBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;position:&lt;/span&gt; &lt;span class="n"&gt;Position&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;// ^ AI knows Position.stack is needed for stacking&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleYContinuous&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;format:&lt;/span&gt; &lt;span class="n"&gt;NumberFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleColorDiscrete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;palette:&lt;/span&gt; &lt;span class="n"&gt;CustomPalette&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;categorical&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChartTheme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;minimal&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Complex data transformations become approachable.&lt;/strong&gt; When you're dealing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-dimensional data mapping&lt;/li&gt;
&lt;li&gt;Statistical transformations&lt;/li&gt;
&lt;li&gt;Custom scales and color palettes&lt;/li&gt;
&lt;li&gt;Animation coordination&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having an AI assistant that understands the grammar makes these advanced features accessible to developers who might otherwise stick to basic charts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technical Implementation: Building an MCP Server
&lt;/h2&gt;

&lt;p&gt;For other package maintainers interested in implementing MCP support, here's what's involved:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. MCP Server Architecture&lt;/strong&gt;&lt;br&gt;
Our MCP server is a lightweight HTTP service that provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Document search and retrieval&lt;/li&gt;
&lt;li&gt;Code example matching&lt;/li&gt;
&lt;li&gt;API reference lookup&lt;/li&gt;
&lt;li&gt;Context-aware responses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Documentation Structure&lt;/strong&gt;&lt;br&gt;
We structure our docs for optimal MCP consumption:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Bubble Charts&lt;/span&gt;
Description: Multi-dimensional data visualization...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Basic Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;CristalyseChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x:&lt;/span&gt; &lt;span class="s"&gt;'x'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;y:&lt;/span&gt; &lt;span class="s"&gt;'y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;size:&lt;/span&gt; &lt;span class="s"&gt;'size'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;geomBubble&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Response Optimization&lt;/strong&gt;&lt;br&gt;
The MCP server returns structured responses that AI assistants can parse effectively:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code examples with syntax highlighting&lt;/li&gt;
&lt;li&gt;API references with parameter details&lt;/li&gt;
&lt;li&gt;Best practices and common patterns&lt;/li&gt;
&lt;li&gt;Error handling guidance&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;p&gt;You might wonder about the performance impact of MCP queries. In practice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Latency&lt;/strong&gt;: ~200-500ms for most queries (similar to searching docs manually)&lt;br&gt;
&lt;strong&gt;Caching&lt;/strong&gt;: Responses are cached by AI assistants&lt;br&gt;
&lt;strong&gt;Offline fallback&lt;/strong&gt;: AI assistants still have their base training knowledge&lt;br&gt;
&lt;strong&gt;Rate limiting&lt;/strong&gt;: Built-in protections prevent abuse&lt;/p&gt;

&lt;p&gt;The performance is more than acceptable for the productivity gains you get.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Implications: The AI-Native Development Era
&lt;/h2&gt;

&lt;p&gt;MCP support in Cristalyse isn't just about convenience - it's a glimpse into how developer tooling will evolve:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain-Specific AI Assistance&lt;/strong&gt;: Instead of generic coding help, you get expert-level guidance in specialized domains like data visualization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contextual Code Generation&lt;/strong&gt;: AI assistants can generate more sophisticated code because they understand the full API surface and best practices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interactive Documentation&lt;/strong&gt;: The line between documentation and development environment disappears.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Collaborative Development&lt;/strong&gt;: AI becomes a true pair programming partner that knows your tools as well as you do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Examples
&lt;/h2&gt;

&lt;p&gt;Here are some queries developers are already using:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complex Data Handling:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;"I have time series data with multiple metrics. How do I create a line chart where each metric has its own Y-axis scale and color?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance Optimization:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;"What's the best way to handle large datasets in Cristalyse? Show me data downsampling and virtualization techniques."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advanced Interactions:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;"How do I implement custom tooltips that show related data when hovering over a point in a scatter plot?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Theme Customization:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;"Create a dark theme for my charts that matches my app's brand colors with proper contrast ratios."&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started Today
&lt;/h2&gt;

&lt;p&gt;Ready to experience AI-assisted chart development? Here's your quickstart:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install Cristalyse&lt;/strong&gt;: &lt;code&gt;flutter pub add cristalyse&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Set up MCP&lt;/strong&gt; in your AI coding assistant (choose one):&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Cursor/Windsurf/Warp&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"cristalyse_docs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://docs.cristalyse.com/mcp"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;# Claude Code CLI&lt;/span&gt;
   claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http cristalyse_docs https://docs.cristalyse.com/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start building&lt;/strong&gt;: Ask your AI assistant anything about Cristalyse&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Share your experience&lt;/strong&gt;: We're actively improving based on developer feedback&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;This is just the beginning. We're working on:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enhanced AI Training&lt;/strong&gt;: Better understanding of chart design principles and data visualization best practices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interactive Examples&lt;/strong&gt;: AI-generated examples that adapt to your specific data structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance Guidance&lt;/strong&gt;: AI assistant that can analyze your chart code and suggest optimizations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integration Recommendations&lt;/strong&gt;: Smart suggestions for integrating charts with your existing Flutter app architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;Cristalyse's MCP integration represents a new category of developer tooling: &lt;strong&gt;AI-native libraries&lt;/strong&gt;. These aren't just packages with good documentation - they're designed from the ground up to work seamlessly with AI development workflows.&lt;/p&gt;

&lt;p&gt;As the Flutter ecosystem evolves, I believe we'll see more packages adopting similar approaches. The combination of powerful, well-designed APIs and AI assistance that deeply understands those APIs will define the next generation of developer productivity tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The question isn't whether AI will change how we write code&lt;/strong&gt; - it's whether our tools will evolve to make that change as powerful as possible.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want to try Cristalyse with MCP support? Check out our &lt;a href="https://docs.cristalyse.com/cristalyse-mcp-server" rel="noopener noreferrer"&gt;setup guide&lt;/a&gt; and start building charts that write themselves.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pub.dev/packages/cristalyse" rel="noopener noreferrer"&gt;Cristalyse on pub.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/rudi-q/cristalyse" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.cristalyse.com" rel="noopener noreferrer"&gt;Complete Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.cristalyse.com/cristalyse-mcp-server" rel="noopener noreferrer"&gt;MCP Setup Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Have you tried AI-assisted development with domain-specific tools? What has your experience been? Let me know in the comments!&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>7 Reasons Flutter Devs Should Use Cristalyse for Charts</title>
      <dc:creator>Rudi K. 🧠</dc:creator>
      <pubDate>Fri, 05 Sep 2025 10:40:20 +0000</pubDate>
      <link>https://dev.to/lofifounder/7-reasons-flutter-devs-should-use-cristalyse-for-charts-54bf</link>
      <guid>https://dev.to/lofifounder/7-reasons-flutter-devs-should-use-cristalyse-for-charts-54bf</guid>
      <description>&lt;p&gt;If you’re a Flutter developer building &lt;strong&gt;dashboards, analytics apps, or reporting tools&lt;/strong&gt;, and you often deal with &lt;strong&gt;large datasets&lt;/strong&gt;, you’ll know how tricky it can be to find a charting library that balances ease of use, performance, and flexibility.&lt;/p&gt;

&lt;p&gt;That’s the gap I tried to solve when building &lt;strong&gt;&lt;a href="https://pub.dev/packages/cristalyse" rel="noopener noreferrer"&gt;Cristalyse&lt;/a&gt;&lt;/strong&gt;. Here are 7 reasons you might find it useful:&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Simple Grammar of Graphics
&lt;/h3&gt;

&lt;p&gt;Cristalyse uses a &lt;strong&gt;grammar of graphics approach&lt;/strong&gt; (inspired by ggplot). Instead of wiring endless widget configs, you describe what you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;CristalyseChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x:&lt;/span&gt; &lt;span class="s"&gt;'month'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;y:&lt;/span&gt; &lt;span class="s"&gt;'revenue'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="s"&gt;'region'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;geomBar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChartTheme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cyberpunk&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Readable, customizable, and much closer to how you think about data.&lt;/p&gt;


&lt;h3&gt;
  
  
  2. Handles 50k+ Data Points Smoothly
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.cristalyse.com/advanced/performance" rel="noopener noreferrer"&gt;Performance&lt;/a&gt; was a big focus. Cristalyse stays responsive even when plotting &lt;strong&gt;tens of thousands of data points&lt;/strong&gt;, so you don’t have to cut corners.&lt;/p&gt;


&lt;h3&gt;
  
  
  3. Built-In Animations and Interactivity
&lt;/h3&gt;

&lt;p&gt;You don’t need extra packages to get the basics right:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smooth &lt;a href="https://docs.cristalyse.com/features/animations" rel="noopener noreferrer"&gt;animations&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Interactive &lt;a href="https://docs.cristalyse.com/features/interactions#basic-panning" rel="noopener noreferrer"&gt;Panning&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tooltips, legends, &lt;a href="https://docs.cristalyse.com/advanced/custom-themes" rel="noopener noreferrer"&gt;theming&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  4. 15+ Chart Types
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.cristalyse.com/charts/bar-charts" rel="noopener noreferrer"&gt;Bar&lt;/a&gt;, &lt;a href="https://docs.cristalyse.com/charts/line-charts" rel="noopener noreferrer"&gt;line&lt;/a&gt;, area, &lt;a href="https://docs.cristalyse.com/charts/scatter-plots" rel="noopener noreferrer"&gt;scatter&lt;/a&gt;, &lt;a href="https://docs.cristalyse.com/charts/bar-charts" rel="noopener noreferrer"&gt;bubble&lt;/a&gt;, &lt;a href="https://docs.cristalyse.com/charts/heat-map-charts" rel="noopener noreferrer"&gt;heatmaps&lt;/a&gt;, grouped bars, stacked bars — and each one is customizable.&lt;/p&gt;


&lt;h3&gt;
  
  
  5. Advanced Features When You Need Them
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.cristalyse.com/charts/dual-axis" rel="noopener noreferrer"&gt;Multiple axes&lt;/a&gt;, categorical coloring, bubble sizing, heatmaps. These are supported natively, so you won’t have to hack your way around them.&lt;/p&gt;


&lt;h3&gt;
  
  
  6. Open Source Under MIT
&lt;/h3&gt;

&lt;p&gt;Cristalyse is &lt;a href="https://github.com/rudi-q/cristalyse" rel="noopener noreferrer"&gt;open source&lt;/a&gt; under the MIT license, so you can use it freely in commercial apps without restrictions.&lt;/p&gt;


&lt;h3&gt;
  
  
  7. Clear, Practical Documentation
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://docs.cristalyse.com" rel="noopener noreferrer"&gt;docs&lt;/a&gt; are written to be straightforward and example-driven, so you can get comfortable in a short amount of time without a steep learning curve.&lt;/p&gt;


&lt;h3&gt;
  
  
  Bonus: GitHub Discussions
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rudi-q" rel="noopener noreferrer"&gt;
        rudi-q
      &lt;/a&gt; / &lt;a href="https://github.com/rudi-q/cristalyse" rel="noopener noreferrer"&gt;
        cristalyse
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      High-performance data visualization library for Flutter with native rendering and cross-platform support
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
  &lt;a href="https://docs.cristalyse.com" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frudi-q%2Fcristalyse%2Fdoc%2Flogo%2Flogo.svg" alt="Cristalyse" width="400"&gt;
  &lt;/a&gt;
  &lt;span&gt;
    &lt;a href="https://github.com/sponsors/rudi-q" rel="noopener noreferrer"&gt;
      &lt;img src="https://camo.githubusercontent.com/5eb439e38f05dbe25ec00fab763d65f38abc13a0452af406a0df546b1fa07e08/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53706f6e736f725f6f6e2d4769744875622d3263616362663f7374796c653d666f722d7468652d6261646765266c6f676f3d67697468756273706f6e736f7273266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d313435323631" alt="Sponsor on GitHub"&gt;
    &lt;/a&gt;
  &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The grammar of graphics visualization library that Flutter developers have been waiting for.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://flutter.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0522e660d2776473bac63a98cced0d49a8c2d9aac7c8907a6b445c81ceba2213/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466c75747465722d332e31332532422d3263616362663f6c6f676f3d666c7574746572266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d313435323631" alt="Flutter support"&gt;&lt;/a&gt;
&lt;a href="https://dart.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f4ec96684ff275b40947170d08ec1ee176da915703fb5f2f7be74f2ac500ebbc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f446172742d332e332e302532422d3263616362663f6c6f676f3d64617274266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d313435323631" alt="Dart support"&gt;&lt;/a&gt;
&lt;a href="https://pub.dev/packages/cristalyse" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5660c1270db1bdc5482f2b6b3a350343bc0428650651d9c381ffeae7d17a16c6/68747470733a2f2f696d672e736869656c64732e696f2f7075622f762f6372697374616c7973652e7376673f636f6c6f723d326361636266266c6162656c436f6c6f723d313435323631" alt="pub package"&gt;&lt;/a&gt;
&lt;a href="https://pub.dev/packages/cristalyse/score" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d94c741cf16b8f43aefc0de0eb220ddc1022f727e4bf3f6c1ae146f3d81a10b6/68747470733a2f2f696d672e736869656c64732e696f2f7075622f706f696e74732f6372697374616c7973653f636f6c6f723d326361636266266c6162656c436f6c6f723d313435323631" alt="pub points"&gt;&lt;/a&gt;
&lt;a href="https://pub.dev/packages/cristalyse/score" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a132a4a5c1561a02586db2d50e9bc01c2ac8fbdce11c042936d7e6e49c239b0c/68747470733a2f2f696d672e736869656c64732e696f2f7075622f6c696b65732f6372697374616c7973653f636f6c6f723d326361636266266c6162656c436f6c6f723d313435323631" alt="likes"&gt;&lt;/a&gt;
&lt;a href="https://pub.dev/packages/cristalyse/score" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/197d78cf7a9d903e8c50b14a99ecd026a4587a05efacd937c6fa97b16368604a/68747470733a2f2f696d672e736869656c64732e696f2f7075622f646d2f6372697374616c7973653f636f6c6f723d326361636266266c6162656c436f6c6f723d313435323631" alt="Pub Downloads"&gt;&lt;/a&gt;
&lt;a href="https://opensource.org/licenses/MIT" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9ec917eeb260cf6bb9dca2d3ea2422189871f4da5ffd46d859c07c556e674c40/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d3263616362662e7376673f6c6162656c436f6c6f723d313435323631" alt="License: MIT"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://flutter.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/987d1ab06ce09548ae8a43a538fdf7592ba5ef701e10549f88cba19a304baddb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5765622d3134353236313f6c6f676f3d676f6f676c652d6368726f6d65266c6f676f436f6c6f723d7768697465" alt="Web"&gt;&lt;/a&gt;
&lt;a href="https://flutter.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4417be0d8cba006f7bec05101a369388ec754a108edb79c9432a26087bae039b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5765625f417373656d626c795f285741534d292d3134353236313f6c6f676f3d776562617373656d626c79266c6f676f436f6c6f723d7768697465" alt="WASM"&gt;&lt;/a&gt;
&lt;a href="https://flutter.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3f74622984835e90f46392e9150fcb47eb1d86afcfa70795865ffad39364f07e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f57696e646f77732d3134353236313f6c6f676f3d57696e646f7773266c6f676f436f6c6f723d7768697465" alt="Windows"&gt;&lt;/a&gt;
&lt;a href="https://flutter.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2773351ebb42339d954165b22a152c08cc76af1fdc5b9e24b1f694d8bc86a881/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61634f532d3134353236313f6c6f676f3d6170706c65266c6f676f436f6c6f723d7768697465" alt="macOS"&gt;&lt;/a&gt;
&lt;a href="https://flutter.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c2b0175f0c28657d3467cd0d5652f4df974086c27d2add00aa395ed8dbd24dd5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c696e75782d3134353236313f6c6f676f3d6c696e7578266c6f676f436f6c6f723d7768697465" alt="Linux"&gt;&lt;/a&gt;
&lt;a href="https://flutter.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d828da869bebf934d884615ce8b5c1de8388a272ede984799d98b32652ab4473/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f416e64726f69642d3134353236313f6c6f676f3d616e64726f6964266c6f676f436f6c6f723d7768697465" alt="Android"&gt;&lt;/a&gt;
&lt;a href="https://flutter.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5f1f708414af7d2bbcf95a8d3c8d35401d2fe62c2b96167716e81db3a9225bd4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f694f532d3134353236313f6c6f676f3d696f73266c6f676f5374796c653d626f6c64266c6f676f436f6c6f723d7768697465" alt="iOS"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.cristalyse.com/cristalyse-mcp-server#claude-code-cli" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8eedfbb38facd96890e679bc1bb397c1445a3be8800ed2b13b57ff9ab351ffe5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436c617564652d4d43505f436c69656e742d3263616362663f6c6f676f3d636c61756465266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d313435323631" alt="Claude Code support"&gt;&lt;/a&gt;
&lt;a href="https://docs.cristalyse.com/cristalyse-mcp-server#ai-code-editor-cursor%2C-windsurf%2C-warp" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/776df14192960d2f88c16bf3dc27b7ba1345d28fad014d2190254aff89697065/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f57696e64737572662d4d43505f436c69656e742d3263616362663f6c6f676f3d77696e6473757266266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d313435323631" alt="Windsurf support"&gt;&lt;/a&gt;
&lt;a href="https://docs.cristalyse.com/cristalyse-mcp-server#ai-code-editor-cursor%2C-windsurf%2C-warp" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/98acd3fb83873e1292b7682e94b20fb98109d5e8882761a7a76da6ab43b89f0f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f5f50696c6f742d4d43505f436c69656e742d3263616362663f6c6f676f3d676974687562636f70696c6f74266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d313435323631" alt="CoPilot support"&gt;&lt;/a&gt;
&lt;a href="https://docs.cristalyse.com/cristalyse-mcp-server#ai-code-editor-cursor%2C-windsurf%2C-warp" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e57416684c1b4e57b43cb1754db6ae93777408c82968b93ecfb7843b1ba5381c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f576172702d4d43505f436c69656e742d3263616362663f6c6f676f3d77617270266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d313435323631" alt="Warp support"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Finally, create beautiful data visualizations in Flutter without fighting against chart widgets or settling for web-based solutions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="45%"&gt;
&lt;p&gt;
  &lt;a href="https://docs.cristalyse.com" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frudi-q%2Fcristalyse%2Fdoc%2Flogo%2Fdark.svg" alt="Cristalyse Documentation" width="400"&gt;
  &lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;Visit our complete documentation for step-by-step guides, interactive examples,&lt;br&gt;and everything you need to master data visualization in Flutter.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://docs.cristalyse.com" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/0d045cb11f985713c36de0524fc2954b2573e8ee24806d8dac4e00ce233e0c33/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f526561645f446f63732d3244333734383f7374796c653d666f722d7468652d6261646765266c6f676f3d6d696e746c696679266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d324433373438" alt="Read Documentation"&gt;
  &lt;/a&gt;
    
  &lt;a href="https://docs.cristalyse.com/quickstart" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/224a1e420ffa3688a10db5602d1f1787ef3ffef83c9cd511216d803443cc5f18/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f517569636b5f53746172742d3441353536383f7374796c653d666f722d7468652d6261646765266c6f676f3d676e6f6d657465726d696e616c266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d344135353638" alt="Quick Start Guide"&gt;
  &lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://docs.cristalyse.com/examples" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/110aa392fb8951a5ad78d81c52d32502c2f6e8b16150e8fa6bbb8e668738ad08/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4578616d706c65732d3731383039363f7374796c653d666f722d7468652d6261646765266c6f676f3d76657263656c266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d373138303936" alt="View Examples"&gt;
  &lt;/a&gt;
    
  &lt;a href="https://github.com/rudi-q/cristalyse" rel="noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/c6881409587839a2639473017317ea38b692beeb1c0b6253c1ea9d5f7b03d1ed/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566965775f536f757263652d3842394443333f7374796c653d666f722d7468652d6261646765266c6f676f3d726566696e6564676974687562266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d384239444333" alt="View Source Code"&gt;
  &lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://cristalyse.com" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/c4a6f8492982b8fe32aed5d23e6ee59c7729358a2766e18ec18e2776d08fef7c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f56697369745f576562736974652d4130414543303f7374796c653d666f722d7468652d6261646765266c6f676f3d617374726f266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d413041454330" alt="Visit Website"&gt;
  &lt;/a&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td width="55%"&gt;
&lt;p&gt;
  &lt;a href="https://docs.cristalyse.com" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frudi-q%2Fcristalyse%2Fdoc%2Fimages%2Fdocumentation.png" alt="Cristalyse Documentation Screenshot" width="70%"&gt;
  &lt;/a&gt;
  &lt;br&gt;
  &lt;em&gt;Comprehensive guides, examples, and API reference&lt;/em&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤖 AI-Powered Development&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Cristalyse Docs now has MCP server&lt;/strong&gt; which you can connect to your AI coding assistant (Cursor, Windsurf, Warp, Claude) for instant access to documentation while you code.&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://docs.cristalyse.com/cristalyse-mcp-server" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/ead1f4ddee2371ea93702734b916928d57d07943dd79f472add8bb77743e00f9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4372697374616c7973655f4d43502d53657475705f47756964652d3263616362663f7374796c653d666f722d7468652d6261646765266c6f676f3d6d6f64656c636f6e7465787470726f746f636f6c266c6f676f436f6c6f723d7768697465266c6162656c436f6c6f723d313435323631" alt="Cristalyse MCP Setup Guide"&gt;
  &lt;/a&gt;
&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Why Cristalyse?&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Stop wrestling with limited chart libraries.&lt;/strong&gt; Cristalyse brings the power of grammar of graphics (think ggplot2) to Flutter with buttery-smooth 60fps animations and true cross-platform deployment.&lt;/p&gt;


&lt;ul&gt;

&lt;li&gt;🎨 &lt;strong&gt;Grammar of Graphics API&lt;/strong&gt; - Familiar syntax if you've used ggplot2 or plotly&lt;/li&gt;

&lt;li&gt;🚀 &lt;strong&gt;Native 60fps Animations&lt;/strong&gt; - Leverages Flutter's rendering engine, not DOM manipulation&lt;/li&gt;

&lt;li&gt;📱 &lt;strong&gt;True Cross-Platform&lt;/strong&gt; - One codebase → Mobile, Web, Desktop…&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rudi-q/cristalyse" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;If you run into questions, there’s a space on &lt;a href="https://github.com/rudi-q/cristalyse/discussions" rel="noopener noreferrer"&gt;GitHub Discussions&lt;/a&gt; where you can ask. I’m actively maintaining Cristalyse, so feedback and issues are always welcome.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cristalyse.com" rel="noopener noreferrer"&gt;Cristalyse&lt;/a&gt; is still evolving, but it’s already usable for real dashboards and applications. If you’ve been struggling with performance or complexity in other libraries, this might give you a smoother experience.&lt;/p&gt;

&lt;p&gt;👉 Try it out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub add cristalyse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docs: &lt;a href="https://docs.cristalyse.com" rel="noopener noreferrer"&gt;docs.cristalyse.com&lt;/a&gt;&lt;br&gt;
Pub Dev: &lt;a href="https://pub.dev/packages/cristalyse" rel="noopener noreferrer"&gt;pub.dev/packages/cristalyse&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/rudi-q/cristalyse" rel="noopener noreferrer"&gt;github.com/rudi-q/cristalyse&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>datascience</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Why I Chose SvelteKit for My PDF Annotation App?</title>
      <dc:creator>Rudi K. 🧠</dc:creator>
      <pubDate>Fri, 05 Sep 2025 06:59:46 +0000</pubDate>
      <link>https://dev.to/lofifounder/why-i-chose-sveltekit-for-my-pdf-annotation-app-2pa2</link>
      <guid>https://dev.to/lofifounder/why-i-chose-sveltekit-for-my-pdf-annotation-app-2pa2</guid>
      <description>&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://leed.my/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fleed.my%2Fog-image.jpg" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://leed.my/" rel="noopener noreferrer" class="c-link"&gt;
            LeedPDF - Draw on PDFs | Free PDF Annotation ToolLeedPDF - Draw on PDFs | Free PDF Annotation Tool
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Add drawings and notes to any PDF with LeedPDF. Free, browser-based PDF annotation tool that works on any device. No uploads required - your files stay private.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fleed.my%2Ffavicon.png"&gt;
          leed.my
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;When I started building &lt;a href="https://leed.my" rel="noopener noreferrer"&gt;LeedPDF&lt;/a&gt;, my goal was simple: make working with PDFs feel less clunky and more natural. A tool where highlighting and sketching felt smooth, not like wrestling with old-school document viewers.&lt;/p&gt;

&lt;p&gt;Choosing the right framework mattered a lot because PDF rendering is already heavy. I didn’t want the framework itself to get in the way. After trying a few options, I settled on &lt;strong&gt;SvelteKit&lt;/strong&gt;. Here’s why it made sense for this project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance with PDF Rendering
&lt;/h2&gt;

&lt;p&gt;Working with PDFs means rendering multiple canvases, text layers, and annotations at once. Even a small amount of overhead adds up fast.&lt;/p&gt;

&lt;p&gt;Svelte compiles components to plain JavaScript, which means smaller bundles and quicker hydration compared to frameworks that carry larger runtimes. That extra efficiency matters when you’re stacking it on top of PDF.js, which is already resource hungry.&lt;/p&gt;

&lt;p&gt;In practice, this kept LeedPDF responsive even on low-end machines.&lt;/p&gt;




&lt;h2&gt;
  
  
  State Management Without Extra Libraries
&lt;/h2&gt;

&lt;p&gt;A PDF annotation app has constant state updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which tool is active (pen, highlight, text)&lt;/li&gt;
&lt;li&gt;Which page you’re on&lt;/li&gt;
&lt;li&gt;Which annotations belong to which page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of wiring up a whole state library, Svelte’s built-in stores and reactive syntax were enough. Stores let me share state across components without ceremony, and reactivity worked without boilerplate.&lt;/p&gt;

&lt;p&gt;This let me focus on annotation logic rather than Redux-style plumbing.&lt;/p&gt;




&lt;h2&gt;
  
  
  SSR and Client Rendering Together
&lt;/h2&gt;

&lt;p&gt;Parts of the project benefit from server-side rendering (landing pages, previews) while others are purely client-side (the actual annotation workspace).&lt;/p&gt;

&lt;p&gt;SvelteKit made it easy to mix both. I could render the marketing pages on the server for speed and SEO, while keeping the core app fully interactive in the browser.&lt;/p&gt;




&lt;h2&gt;
  
  
  Routing That Fits the App
&lt;/h2&gt;

&lt;p&gt;LeedPDF has separate modes: view, annotate, settings. I wanted clear routes but not extra config files to maintain.&lt;/p&gt;

&lt;p&gt;SvelteKit’s file-based routing worked well. I could set up routes like &lt;code&gt;/view/[id]&lt;/code&gt; or &lt;code&gt;/annotate/[id]&lt;/code&gt; quickly, and layouts helped me avoid repeating UI elements.&lt;/p&gt;




&lt;h2&gt;
  
  
  Integrating with PDF.js
&lt;/h2&gt;

&lt;p&gt;The real backbone of the app is Mozilla’s PDF.js. Wrapping it into reusable components can get messy in some frameworks because of lifecycle quirks.&lt;/p&gt;

&lt;p&gt;With Svelte, I could map PDF.js rendering outputs (canvas, text layers) directly into reactive components. This kept the integration clean and easier to maintain.&lt;/p&gt;




&lt;h2&gt;
  
  
  Developer Experience
&lt;/h2&gt;

&lt;p&gt;Since LeedPDF started as a Friday hack project, speed of iteration mattered. SvelteKit, powered by Vite, gave me quick reloads and a straightforward project setup.&lt;/p&gt;

&lt;p&gt;That low friction meant I could spend weekends adding features instead of debugging configs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;I didn’t pick SvelteKit because it was trendy. It turned out to be the right fit because it handled the performance demands, reduced boilerplate, and played nicely with the specific needs of a PDF annotation tool.&lt;/p&gt;

&lt;p&gt;If you’re curious about the implementation, the full source code is here 👇&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rudi-q" rel="noopener noreferrer"&gt;
        rudi-q
      &lt;/a&gt; / &lt;a href="https://github.com/rudi-q/leed_pdf_viewer" rel="noopener noreferrer"&gt;
        leed_pdf_viewer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Open-source PDF annotation and drawing tool built for privacy. Sketch and annotate PDFs with natural pen-like precision, drawing tablet support. SvelteKit + Tauri.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/rudi-q/leed_pdf_viewer/static/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frudi-q%2Fleed_pdf_viewer%2Fstatic%2Flogo.png" alt="LeedPDF Logo" width="160" height="160"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;LeedPDF - Free PDF Annotation Tool&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Add drawings and notes to any PDF.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Works with mouse, touch, or stylus - completely free and private.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="https://www.gnu.org/licenses/agpl-3.0" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8864ac9cd55989c144d1fe4ee4b950248f137882a313d77b4e4b16773a5498d7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4147504c253230332e302d3837413936422e737667" alt="License: AGPL-3.0"&gt;&lt;/a&gt;
&lt;a href="https://buy.polar.sh/polar_cl_tPmQ3d72uYwrYvzzIUM4R7cku7hg2kmEQqruI1its5c" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ae509ba2ee2fa4b9861c5b93a74f9c4a330d3353716df44df736a0965dc7924e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6d6d65726369616c2532304c6963656e73652d417661696c61626c652d3837413936422e737667" alt="Commercial License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/leed_pdf_viewer#web-app-agpl" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c96f38dc1d8702008d09dc544805f8e926a482147ef5471dabb99c4eb5237f55/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f467265652d5765622532304170702d3837413936422e737667" alt="Free for Personal Use on Web"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/leed_pdf_viewer/stargazers" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/63e0e95f939d0283e6645c454772dfa109604d985f81efde673209b879c405ef/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f727564692d712f6c6565645f7064665f7669657765723f636f6c6f723d383741393642267374796c653d666c6174266c6f676f3d676974687562" alt="GitHub Stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/leed_pdf_viewer/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/53a02b91f69f5ea22a10e79ec7e7df07f9c517dfcafc5838b2c2035f7f2da2f0/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f727564692d712f6c6565645f7064665f7669657765722f746f74616c3f6c6162656c3d446f776e6c6f616473266c6f676f3d67697468756226636f6c6f723d383741393642" alt="Downloads"&gt;&lt;/a&gt;
&lt;a href="https://www.w3.org/WAI/WCAG2AAA-Conformance" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/af13df82bbd406f340b90e810933a1aaf2e596959e18a29a9c09aed9f53414ef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f574341472532304141412d436f6d706c69616e742d3837413936423f7374796c653d666c6174266c6f676f3d6163636573736962696c697479616c74266c6f676f436f6c6f723d7768697465" alt="WCAG AAA Compliant"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://kit.svelte.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bbb59172a14b8fd9aa9753bf59874d4b24b5484004753f84f70fe36594c0da78/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5376656c74654b69742d4646334530303f7374796c653d666c6174266c6f676f3d7376656c7465266c6f676f436f6c6f723d7768697465" alt="SvelteKit"&gt;&lt;/a&gt;
&lt;a href="https://www.typescriptlang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3414bd6550fc1cbc705d8b6f6a0703edd60842f3e422a97853b052f8b4ff13bf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f547970655363726970742d3030374143433f7374796c653d666c6174266c6f676f3d74797065736372697074266c6f676f436f6c6f723d7768697465" alt="TypeScript"&gt;&lt;/a&gt;
&lt;a href="https://tauri.app/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3a37b78df4166b59d8e039c261cb48ccd78b4804eb4c33c01affc1d7d1471a6a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54617572692d3234433844383f7374796c653d666c6174266c6f676f3d7461757269266c6f676f436f6c6f723d7768697465" alt="Tauri"&gt;&lt;/a&gt;
&lt;a href="https://mozilla.github.io/pdf.js/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9396c2a0f0db22ffb38e68b1730685ad77f1af524ae10d1799a66a4bc6a5c0ef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5044462e6a732d3030303030303f7374796c653d666c6174266c6f676f3d6d6f7a696c6c61266c6f676f436f6c6f723d7768697465" alt="PDF.js"&gt;&lt;/a&gt;
&lt;a href="https://api.search.brave.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1739154a7273bfd45341848945e4cd47b6d30f79f817469974ed57e7b2cdf089/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f42726176652532305365617263682d4642353432423f7374796c653d666c6174266c6f676f3d6272617665266c6f676f436f6c6f723d7768697465" alt="Brave Search API"&gt;&lt;/a&gt;
&lt;a href="https://tailwindcss.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6b9d37def8afc480d0b20fc34c6717b709a58b4262fbf52e4edb32b5b40d83c8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5461696c77696e645f4353532d3036423644343f7374796c653d666c6174266c6f676f3d7461696c77696e64637373266c6f676f436f6c6f723d7768697465" alt="Tailwind CSS"&gt;&lt;/a&gt;
&lt;a href="https://vitejs.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/19bbe6aeb3a1d66722d8359bda2903e7d5c69e234fa5b43adeda5dfe93fbe512/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566974652d3634364346463f7374796c653d666c6174266c6f676f3d76697465266c6f676f436f6c6f723d7768697465" alt="Vite"&gt;&lt;/a&gt;
&lt;a href="https://coderabbit.ai/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/84cf4d6d96afbc870ee06cac1f447b22070497616a66e721b733cdd22515f4d5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f64655261626269742d4646353730413f7374796c653d666c6174266c6f676f3d636f6465726162626974266c6f676f436f6c6f723d7768697465" alt="CodeRabbit"&gt;&lt;/a&gt;
&lt;a href="https://appwrite.io/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ff06d4540d47a0468dff1e8c72d80c36a8369ee974d251d2a839d7de744d2baa/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f41707077726974652d4630324536353f7374796c653d666c6174266c6f676f3d6170707772697465266c6f676f436f6c6f723d7768697465" alt="Appwrite"&gt;&lt;/a&gt;
&lt;a href="https://vercel.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fe48bc13928ab2395c1293aea537972cd0369cf6a6db11f2f242cb5565711557/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f56657263656c2d3030303030303f7374796c653d666c6174266c6f676f3d76657263656c266c6f676f436f6c6f723d7768697465" alt="Vercel"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;A modern, open-source PDF annotation tool that runs entirely in your browser&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Transform any PDF into an interactive canvas. Draw, annotate, and collaborate without uploading your documents to external servers.&lt;/p&gt;
&lt;div&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/rudi-q/leed_pdf_viewer/static/screenshot.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frudi-q%2Fleed_pdf_viewer%2Fstatic%2Fscreenshot.png" alt="LeedPDF in action - annotating a Y Combinator fundraising guide with highlights, comments, and drawings" width="800"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://leed.my" rel="nofollow noopener noreferrer"&gt;&lt;strong&gt;Try it now →&lt;/strong&gt;&lt;/a&gt; | &lt;a href="https://github.com/rudi-q/leed_pdf_viewer/issues" rel="noopener noreferrer"&gt;&lt;strong&gt;Report Issues&lt;/strong&gt;&lt;/a&gt; | &lt;a href="https://github.com/rudi-q/leed_pdf_viewer/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;&lt;strong&gt;Contribute&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🔍 &lt;strong&gt;PDF Search &amp;amp; Discovery&lt;/strong&gt;
&lt;/h3&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web-wide PDF search&lt;/strong&gt; powered by Brave Search API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct PDF opening&lt;/strong&gt; from search results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart filtering&lt;/strong&gt; for PDF documents only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pagination&lt;/strong&gt; through search results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time search&lt;/strong&gt; with instant results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Setup guide&lt;/strong&gt;: See &lt;a href="https://github.com/rudi-q/leed_pdf_viewer/docs/SEARCH_FEATURE.md" rel="noopener noreferrer"&gt;docs/SEARCH_FEATURE.md&lt;/a&gt; for configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🎨 &lt;strong&gt;Drawing &amp;amp; Annotation&lt;/strong&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Freehand drawing&lt;/strong&gt; with customizable pencil and highlighter tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shape tools&lt;/strong&gt; including rectangles, circles, arrows, and stars&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text annotations&lt;/strong&gt; with inline editing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sticky notes&lt;/strong&gt; for quick comments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart eraser&lt;/strong&gt; that removes intersecting elements&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;📱 &lt;strong&gt;Universal Access&lt;/strong&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Works on &lt;strong&gt;any device&lt;/strong&gt; -…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rudi-q/leed_pdf_viewer" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Feel free to explore (and maybe leave a star ⭐).&lt;/p&gt;

&lt;p&gt;For anyone who just wants to try it out, the live web version is here: &lt;a href="https://leed.my" rel="noopener noreferrer"&gt;leed.my&lt;/a&gt;&lt;br&gt;
.&lt;/p&gt;

&lt;p&gt;LeedPDF is &lt;strong&gt;open source&lt;/strong&gt; under AGPL, and the web version will always be &lt;strong&gt;free&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Built LeedPDF - Open Source PDF Drawing &amp; Annotation That Feels Like Sketching ✏️</title>
      <dc:creator>Rudi K. 🧠</dc:creator>
      <pubDate>Wed, 06 Aug 2025 14:29:04 +0000</pubDate>
      <link>https://dev.to/lofifounder/i-built-leedpdf-open-source-pdf-drawing-annotation-that-feels-like-sketching-3n9n</link>
      <guid>https://dev.to/lofifounder/i-built-leedpdf-open-source-pdf-drawing-annotation-that-feels-like-sketching-3n9n</guid>
      <description>&lt;p&gt;I’ve always loved the feeling of scribbling on paper with a pencil, especially when reviewing documents, sketching ideas, or just making quick notes.&lt;/p&gt;

&lt;p&gt;But every PDF annotation tool I tried felt too mechanical. Either the brush felt fake, the UI was clunky, or the entire experience was built around highlighting text rather than drawing freely. And as someone who uses a drawing tablet regularly, it always felt like these tools weren’t made for me.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1952788843855564859-558" src="https://platform.twitter.com/embed/Tweet.html?id=1952788843855564859"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1952788843855564859-558');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1952788843855564859&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://leed.my" rel="noopener noreferrer"&gt;LeedPDF&lt;/a&gt;.&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.amazonaws.com%2Fuploads%2Farticles%2Fd2xq1vtv0uh39qhb25c2.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.amazonaws.com%2Fuploads%2Farticles%2Fd2xq1vtv0uh39qhb25c2.png" alt="Upload or Drag your PDF to LeedPDF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s a lightweight, open-source PDF drawing and annotation tool that feels more like sketching on paper than clicking through buttons.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rudi-q" rel="noopener noreferrer"&gt;
        rudi-q
      &lt;/a&gt; / &lt;a href="https://github.com/rudi-q/leed_pdf_viewer" rel="noopener noreferrer"&gt;
        leed_pdf_viewer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Open-source PDF annotation and drawing tool built for privacy. Sketch and annotate PDFs with natural pen-like precision, drawing tablet support. SvelteKit + Tauri.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/rudi-q/leed_pdf_viewer/static/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frudi-q%2Fleed_pdf_viewer%2Fstatic%2Flogo.png" alt="LeedPDF Logo" width="160" height="160"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;LeedPDF - Free PDF Annotation Tool&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Add drawings and notes to any PDF.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Works with mouse, touch, or stylus - completely free and private.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="https://www.gnu.org/licenses/agpl-3.0" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8864ac9cd55989c144d1fe4ee4b950248f137882a313d77b4e4b16773a5498d7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4147504c253230332e302d3837413936422e737667" alt="License: AGPL-3.0"&gt;&lt;/a&gt;
&lt;a href="https://buy.polar.sh/polar_cl_tPmQ3d72uYwrYvzzIUM4R7cku7hg2kmEQqruI1its5c" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ae509ba2ee2fa4b9861c5b93a74f9c4a330d3353716df44df736a0965dc7924e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6d6d65726369616c2532304c6963656e73652d417661696c61626c652d3837413936422e737667" alt="Commercial License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/leed_pdf_viewer#web-app-agpl" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c96f38dc1d8702008d09dc544805f8e926a482147ef5471dabb99c4eb5237f55/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f467265652d5765622532304170702d3837413936422e737667" alt="Free for Personal Use on Web"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/leed_pdf_viewer/stargazers" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/63e0e95f939d0283e6645c454772dfa109604d985f81efde673209b879c405ef/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f727564692d712f6c6565645f7064665f7669657765723f636f6c6f723d383741393642267374796c653d666c6174266c6f676f3d676974687562" alt="GitHub Stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/rudi-q/leed_pdf_viewer/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/53a02b91f69f5ea22a10e79ec7e7df07f9c517dfcafc5838b2c2035f7f2da2f0/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f727564692d712f6c6565645f7064665f7669657765722f746f74616c3f6c6162656c3d446f776e6c6f616473266c6f676f3d67697468756226636f6c6f723d383741393642" alt="Downloads"&gt;&lt;/a&gt;
&lt;a href="https://www.w3.org/WAI/WCAG2AAA-Conformance" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/af13df82bbd406f340b90e810933a1aaf2e596959e18a29a9c09aed9f53414ef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f574341472532304141412d436f6d706c69616e742d3837413936423f7374796c653d666c6174266c6f676f3d6163636573736962696c697479616c74266c6f676f436f6c6f723d7768697465" alt="WCAG AAA Compliant"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://kit.svelte.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bbb59172a14b8fd9aa9753bf59874d4b24b5484004753f84f70fe36594c0da78/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5376656c74654b69742d4646334530303f7374796c653d666c6174266c6f676f3d7376656c7465266c6f676f436f6c6f723d7768697465" alt="SvelteKit"&gt;&lt;/a&gt;
&lt;a href="https://www.typescriptlang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3414bd6550fc1cbc705d8b6f6a0703edd60842f3e422a97853b052f8b4ff13bf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f547970655363726970742d3030374143433f7374796c653d666c6174266c6f676f3d74797065736372697074266c6f676f436f6c6f723d7768697465" alt="TypeScript"&gt;&lt;/a&gt;
&lt;a href="https://tauri.app/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3a37b78df4166b59d8e039c261cb48ccd78b4804eb4c33c01affc1d7d1471a6a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54617572692d3234433844383f7374796c653d666c6174266c6f676f3d7461757269266c6f676f436f6c6f723d7768697465" alt="Tauri"&gt;&lt;/a&gt;
&lt;a href="https://mozilla.github.io/pdf.js/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9396c2a0f0db22ffb38e68b1730685ad77f1af524ae10d1799a66a4bc6a5c0ef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5044462e6a732d3030303030303f7374796c653d666c6174266c6f676f3d6d6f7a696c6c61266c6f676f436f6c6f723d7768697465" alt="PDF.js"&gt;&lt;/a&gt;
&lt;a href="https://api.search.brave.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1739154a7273bfd45341848945e4cd47b6d30f79f817469974ed57e7b2cdf089/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f42726176652532305365617263682d4642353432423f7374796c653d666c6174266c6f676f3d6272617665266c6f676f436f6c6f723d7768697465" alt="Brave Search API"&gt;&lt;/a&gt;
&lt;a href="https://tailwindcss.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6b9d37def8afc480d0b20fc34c6717b709a58b4262fbf52e4edb32b5b40d83c8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5461696c77696e645f4353532d3036423644343f7374796c653d666c6174266c6f676f3d7461696c77696e64637373266c6f676f436f6c6f723d7768697465" alt="Tailwind CSS"&gt;&lt;/a&gt;
&lt;a href="https://vitejs.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/19bbe6aeb3a1d66722d8359bda2903e7d5c69e234fa5b43adeda5dfe93fbe512/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566974652d3634364346463f7374796c653d666c6174266c6f676f3d76697465266c6f676f436f6c6f723d7768697465" alt="Vite"&gt;&lt;/a&gt;
&lt;a href="https://coderabbit.ai/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/84cf4d6d96afbc870ee06cac1f447b22070497616a66e721b733cdd22515f4d5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f64655261626269742d4646353730413f7374796c653d666c6174266c6f676f3d636f6465726162626974266c6f676f436f6c6f723d7768697465" alt="CodeRabbit"&gt;&lt;/a&gt;
&lt;a href="https://appwrite.io/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ff06d4540d47a0468dff1e8c72d80c36a8369ee974d251d2a839d7de744d2baa/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f41707077726974652d4630324536353f7374796c653d666c6174266c6f676f3d6170707772697465266c6f676f436f6c6f723d7768697465" alt="Appwrite"&gt;&lt;/a&gt;
&lt;a href="https://vercel.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fe48bc13928ab2395c1293aea537972cd0369cf6a6db11f2f242cb5565711557/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f56657263656c2d3030303030303f7374796c653d666c6174266c6f676f3d76657263656c266c6f676f436f6c6f723d7768697465" alt="Vercel"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;A modern, open-source PDF annotation tool that runs entirely in your browser&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Transform any PDF into an interactive canvas. Draw, annotate, and collaborate without uploading your documents to external servers.&lt;/p&gt;
&lt;div&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/rudi-q/leed_pdf_viewer/static/screenshot.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Frudi-q%2Fleed_pdf_viewer%2Fstatic%2Fscreenshot.png" alt="LeedPDF in action - annotating a Y Combinator fundraising guide with highlights, comments, and drawings" width="800"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://leed.my" rel="nofollow noopener noreferrer"&gt;&lt;strong&gt;Try it now →&lt;/strong&gt;&lt;/a&gt; | &lt;a href="https://github.com/rudi-q/leed_pdf_viewer/issues" rel="noopener noreferrer"&gt;&lt;strong&gt;Report Issues&lt;/strong&gt;&lt;/a&gt; | &lt;a href="https://github.com/rudi-q/leed_pdf_viewer/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;&lt;strong&gt;Contribute&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🔍 &lt;strong&gt;PDF Search &amp;amp; Discovery&lt;/strong&gt;
&lt;/h3&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web-wide PDF search&lt;/strong&gt; powered by Brave Search API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct PDF opening&lt;/strong&gt; from search results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart filtering&lt;/strong&gt; for PDF documents only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pagination&lt;/strong&gt; through search results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time search&lt;/strong&gt; with instant results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Setup guide&lt;/strong&gt;: See &lt;a href="https://github.com/rudi-q/leed_pdf_viewer/docs/SEARCH_FEATURE.md" rel="noopener noreferrer"&gt;docs/SEARCH_FEATURE.md&lt;/a&gt; for configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🎨 &lt;strong&gt;Drawing &amp;amp; Annotation&lt;/strong&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Freehand drawing&lt;/strong&gt; with customizable pencil and highlighter tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shape tools&lt;/strong&gt; including rectangles, circles, arrows, and stars&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text annotations&lt;/strong&gt; with inline editing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sticky notes&lt;/strong&gt; for quick comments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart eraser&lt;/strong&gt; that removes intersecting elements&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;📱 &lt;strong&gt;Universal Access&lt;/strong&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Works on &lt;strong&gt;any device&lt;/strong&gt; -…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rudi-q/leed_pdf_viewer" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;I use a drawing tablet daily, and every PDF tool I tried felt… off. Brushes were too perfect, pressure input was ignored, and the overall experience felt clunky. &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.amazonaws.com%2Fuploads%2Farticles%2F90k1xc1xtdq6ryx14nry.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.amazonaws.com%2Fuploads%2Farticles%2F90k1xc1xtdq6ryx14nry.png" alt="Read, Skim, Search in your docs with LeedPDF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wasn’t looking for another all-in-one editor — just a space where I could mark up PDFs freely, like I do in my sketchbook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://leed.my" rel="noopener noreferrer"&gt;LeedPDF&lt;/a&gt;&lt;/strong&gt; is built for that.&lt;/p&gt;

&lt;p&gt;How It Works 🤔&lt;/p&gt;

&lt;p&gt;LeedPDF is built using SvelteKit with a custom drawing engine that supports pressure-sensitive strokes, natural brush feel, and minimal UI distraction.&lt;/p&gt;

&lt;p&gt;It’s fully offline-ready. No logins. No syncing. Your files stay on your device.&lt;/p&gt;

&lt;p&gt;And it’s not just a web app...&lt;/p&gt;

&lt;p&gt;💻 LeedPDF also comes as a lightweight desktop app if you prefer working outside the browser.&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.amazonaws.com%2Fuploads%2Farticles%2F87kvci7i9uuv4yfok6r5.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.amazonaws.com%2Fuploads%2Farticles%2F87kvci7i9uuv4yfok6r5.png" alt="Highlight, Comment, Doodle, Do it your way on LeedPDF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Features&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pressure-sensitive drawing&lt;/li&gt;
&lt;li&gt;Natural sketch-like brush strokes&lt;/li&gt;
&lt;li&gt;Works offline (browser &amp;amp; desktop)&lt;/li&gt;
&lt;li&gt;No accounts, no tracking&lt;/li&gt;
&lt;li&gt;Open source&lt;/li&gt;
&lt;li&gt;Built with SvelteKit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧪 Try It&lt;/p&gt;

&lt;p&gt;Use it right away in your browser:&lt;br&gt;
👉 &lt;a href="https://leed.my" rel="noopener noreferrer"&gt;https://leed.my&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or download the desktop version from the GitHub releases:&lt;br&gt;
🔗 &lt;a href="https://leed.my/downloads" rel="noopener noreferrer"&gt;https://leed.my/downloads&lt;/a&gt;&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.amazonaws.com%2Fuploads%2Farticles%2F4jhhe45becwtalyj4h0h.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.amazonaws.com%2Fuploads%2Farticles%2F4jhhe45becwtalyj4h0h.png" alt="Also in dark mode, your call."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Final Thoughts 💭&lt;/p&gt;

&lt;p&gt;LeedPDF is the kind of tool I wish existed years ago — and now I use it daily.&lt;/p&gt;

&lt;p&gt;If you prefer drawing your thoughts over typing them, or if traditional PDF tools never quite clicked for you, give it a spin. &lt;br&gt;
Always open to feedback, ideas, or contributions.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>svelte</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I made my first game with flutter, it's open-source</title>
      <dc:creator>Rudi K. 🧠</dc:creator>
      <pubDate>Sat, 05 Jul 2025 20:57:16 +0000</pubDate>
      <link>https://dev.to/lofifounder/i-made-my-first-game-with-flutter-its-open-source-pid</link>
      <guid>https://dev.to/lofifounder/i-made-my-first-game-with-flutter-its-open-source-pid</guid>
      <description>&lt;p&gt;made my first game with flutter 💙&lt;/p&gt;

&lt;p&gt;it’s called tuesdae rush, a traffic sim game&lt;/p&gt;

&lt;p&gt;you use arrow keys to switch traffic lights and try not to cause a mess&lt;/p&gt;

&lt;p&gt;free to play, obv 🙂&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://tuesdae.games" rel="noopener noreferrer"&gt;https://tuesdae.games&lt;/a&gt; 🚦&lt;/p&gt;

&lt;p&gt;would love to hear what you think&lt;/p&gt;

&lt;p&gt;it's also now open source&lt;br&gt;
just felt right to make it public&lt;br&gt;
feel free to explore, learn, or build your own version for fun&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rudi-q/tuesdae-rush" rel="noopener noreferrer"&gt;https://github.com/rudi-q/tuesdae-rush&lt;/a&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fe871nj4txn37zoo04la2.gif" 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.amazonaws.com%2Fuploads%2Farticles%2Fe871nj4txn37zoo04la2.gif" alt="Tuesdae Rush: A Unique Game Experience on Control and Letting Go" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>opensource</category>
      <category>flutter</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Introducing Cristalyse: Grammar of Graphics Charts for Flutter</title>
      <dc:creator>Rudi K. 🧠</dc:creator>
      <pubDate>Sat, 05 Jul 2025 19:50:12 +0000</pubDate>
      <link>https://dev.to/lofifounder/introducing-cristalyse-grammar-of-graphics-charts-for-flutter-2c2i</link>
      <guid>https://dev.to/lofifounder/introducing-cristalyse-grammar-of-graphics-charts-for-flutter-2c2i</guid>
      <description>&lt;p&gt;If you've ever tried to build decent data visualizations in Flutter, you know the pain. You either get stuck with basic chart widgets that look like they're from 2010, or you end up embedding web views just to use D3.js. Neither feels great.&lt;/p&gt;

&lt;p&gt;As someone who has a CS degree focused on data analytics, I spent way too much time fighting with fl_chart and charts_flutter. They're fine for simple stuff, but the moment you need anything remotely sophisticated, you're out of luck.&lt;/p&gt;

&lt;p&gt;Don't get me wrong - those libraries serve their purpose. But when you need dual y-axes, custom interactions, or anything beyond basic bar/line charts, you're basically SOL.&lt;/p&gt;

&lt;p&gt;So I built Cristalyse.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's different about it?
&lt;/h3&gt;

&lt;p&gt;It's based on grammar of graphics (think ggplot2 if you've used R). Instead of rigid chart widgets, you build visualizations by layering data, mappings, and geometries.&lt;/p&gt;

&lt;p&gt;Here's what a scatter plot looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;CristalyseChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'x'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'y'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'category'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'x'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'y'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'category'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'B'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'x'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'y'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'category'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x:&lt;/span&gt; &lt;span class="s"&gt;'x'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;y:&lt;/span&gt; &lt;span class="s"&gt;'y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="s"&gt;'category'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;geomPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;size:&lt;/span&gt; &lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;alpha:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleXContinuous&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleYContinuous&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChartTheme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;defaultTheme&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare that to the usual Flutter chart setup where you're passing in a dozen different widget properties and hoping for the best.&lt;/p&gt;

&lt;h3&gt;
  
  
  Actually useful features
&lt;/h3&gt;

&lt;p&gt;The stuff I was missing in other libraries:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dual Y-axis support&lt;/strong&gt; - Because sometimes you need to plot revenue and user count on the same chart without everything looking broken. Most Flutter chart libraries either don't support this or make it incredibly painful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proper animations&lt;/strong&gt; - 60fps smooth transitions that leverage Flutter's rendering engine. Not the janky CSS-style animations you get with web-based solutions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real theming&lt;/strong&gt; - Change colors, fonts, spacing, grid styles, whatever. No more "this chart library only supports 5 preset themes" nonsense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SVG export&lt;/strong&gt; - For when your PM asks for "just a quick chart for the presentation" (we've all been there). Works across all platforms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interactive tooltips&lt;/strong&gt; - Hover states that actually work and look professional. Pan and zoom that feels natural.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple geometries&lt;/strong&gt; - Layer different chart types on the same plot. Scatter plots with trend lines, bar charts with reference lines, whatever makes sense for your data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real world example
&lt;/h3&gt;

&lt;p&gt;Here's something I built recently - a dashboard showing user engagement over time with conversion events overlaid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;CristalyseChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;analyticsData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x:&lt;/span&gt; &lt;span class="s"&gt;'date'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;y:&lt;/span&gt; &lt;span class="s"&gt;'activeUsers'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mappingY2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'conversions'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;geomLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;yAxis:&lt;/span&gt; &lt;span class="n"&gt;YAxis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;strokeWidth:&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;geomPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;yAxis:&lt;/span&gt; &lt;span class="n"&gt;YAxis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;size:&lt;/span&gt; &lt;span class="mf"&gt;8.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleXContinuous&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleYContinuous&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;min:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scaleY2Continuous&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;min:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ChartTheme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;defaultTheme&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try doing that cleanly with fl_chart. I'll wait.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance that doesn't suck
&lt;/h3&gt;

&lt;p&gt;I benchmarked this against the popular Flutter chart libraries with a dataset of 10k points. Cristalyse consistently outperformed them, especially on animations and interactions. The secret sauce is leveraging Flutter's CustomPainter directly instead of building complex widget trees.&lt;/p&gt;

&lt;p&gt;Plus, since it's not web-based, you don't get the typical "works great in Chrome, terrible everywhere else" experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cross-platform without the headaches
&lt;/h3&gt;

&lt;p&gt;The best part? It works everywhere Flutter works. Mobile, web, desktop, all from the same code. No platform-specific chart libraries, no "oh this doesn't work on web" surprises.&lt;/p&gt;

&lt;p&gt;I've been using it for dashboards in my own projects and it's been solid. The performance is actually better than the web-based solutions because it's using Flutter's rendering engine instead of fighting with DOM manipulation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why grammar of graphics matters
&lt;/h3&gt;

&lt;p&gt;If you've never used ggplot2 or similar libraries, the grammar of graphics approach might seem weird at first. But it's incredibly powerful once it clicks.&lt;/p&gt;

&lt;p&gt;Instead of having separate widgets for LineChart, BarChart, ScatterPlot, etc., you have one Chart widget that you compose different layers onto. Want a scatter plot with a trend line? Add both geomPoint() and geomSmooth(). Want to color code by category? Map a column to the color aesthetic.&lt;/p&gt;

&lt;p&gt;This composability means you can create complex visualizations that would be impossible (or really ugly) with traditional chart widgets.&lt;/p&gt;

&lt;h3&gt;
  
  
  The technical stuff
&lt;/h3&gt;

&lt;p&gt;Under the hood, Cristalyse uses Flutter's CustomPainter for rendering, which gives us direct access to the canvas. This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better performance than widget-heavy approaches&lt;/li&gt;
&lt;li&gt;Smooth animations using Flutter's animation framework&lt;/li&gt;
&lt;li&gt;Consistent rendering across all platforms&lt;/li&gt;
&lt;li&gt;Easy integration with Flutter's existing theming system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The data processing pipeline handles missing values gracefully, supports different data types (numeric, categorical, datetime), and includes basic statistical transformations out of the box.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try it out
&lt;/h3&gt;

&lt;p&gt;It's on pub.dev as &lt;code&gt;cristalyse&lt;/code&gt;. Check out &lt;a href="https://cristalyse.com" rel="noopener noreferrer"&gt;cristalyse.com&lt;/a&gt; for examples and getting started info, or jump straight to the full documentation at &lt;a href="https://docs.cristalyse.com" rel="noopener noreferrer"&gt;docs.cristalyse.com&lt;/a&gt; with interactive examples and a proper quickstart guide.&lt;/p&gt;

&lt;p&gt;The docs site has live code examples you can copy-paste, plus a gallery of different chart types with complete source code.&lt;/p&gt;

&lt;p&gt;Fair warning: it's still early days (version 0.9.3), so expect some rough edges. But it's functional enough that I'm using it in production for client projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's next
&lt;/h3&gt;

&lt;p&gt;Working on a few things for the next release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Histogram and density plots&lt;/li&gt;
&lt;li&gt;Better mobile touch interactions
&lt;/li&gt;
&lt;li&gt;More statistical transformations (smoothing, regression lines)&lt;/li&gt;
&lt;li&gt;Faceting support for small multiples&lt;/li&gt;
&lt;li&gt;Better integration with common Flutter state management patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've been frustrated with Flutter's chart situation, give it a shot. The &lt;a href="https://github.com/rudi-q/cristalyse" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; is open for issues, feature requests, or if you want to contribute.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built this because I needed it, figured others might too. Source is on &lt;a href="https://github.com/rudi-q/cristalyse" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; if you want to poke around or contribute.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>opensource</category>
      <category>charts</category>
    </item>
  </channel>
</rss>
