<?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: Vasanth</title>
    <description>The latest articles on DEV Community by Vasanth (@vasanth-rb).</description>
    <link>https://dev.to/vasanth-rb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4039719%2F5af05e68-dc88-4dde-8966-5887d58a4618.JPG</url>
      <title>DEV Community: Vasanth</title>
      <link>https://dev.to/vasanth-rb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vasanth-rb"/>
    <language>en</language>
    <item>
      <title>I built another React file uploader. But this time, I built it for AI agents too.</title>
      <dc:creator>Vasanth</dc:creator>
      <pubDate>Wed, 22 Jul 2026 14:30:12 +0000</pubDate>
      <link>https://dev.to/vasanth-rb/i-built-another-react-file-uploader-but-this-time-i-built-it-for-ai-agents-too-5cbc</link>
      <guid>https://dev.to/vasanth-rb/i-built-another-react-file-uploader-but-this-time-i-built-it-for-ai-agents-too-5cbc</guid>
      <description>&lt;p&gt;When we started building the upload system for our new product, I did what every engineer does—I looked at the existing ecosystem first.&lt;/p&gt;

&lt;p&gt;There are already some fantastic open source libraries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/react-dropzone/react-dropzone" rel="noopener noreferrer"&gt;react-dropzone&lt;/a&gt;&lt;/strong&gt; is excellent if all you need is drag-and-drop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/transloadit/uppy" rel="noopener noreferrer"&gt;Uppy&lt;/a&gt;&lt;/strong&gt; is feature-rich and supports almost every upload scenario you can imagine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/pqina/filepond" rel="noopener noreferrer"&gt;FilePond&lt;/a&gt;&lt;/strong&gt; is polished and battle-tested.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But our requirement was different.&lt;/p&gt;

&lt;p&gt;We weren't looking for an upload ecosystem. We wanted a lightweight, headless uploader with a clean transport abstraction that could grow with our product.&lt;/p&gt;

&lt;p&gt;So I started building one.&lt;/p&gt;

&lt;p&gt;At first, it was simply an internal component.&lt;/p&gt;

&lt;p&gt;Then I paused.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do we really need another OSS library?
&lt;/h2&gt;

&lt;p&gt;We're living in an era where AI can scaffold components from a prompt.&lt;/p&gt;

&lt;p&gt;Need a file uploader?&lt;/p&gt;

&lt;p&gt;Cursor, Claude Code, Copilot, or v0 can generate one in seconds.&lt;/p&gt;

&lt;p&gt;So the obvious question became:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Do we actually need another open source library?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For a while, I thought maybe we didn't.&lt;/p&gt;

&lt;p&gt;Then I realized I was asking the wrong question.&lt;/p&gt;

&lt;p&gt;The better question was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If we're building open source today, what should an AI-native library look like?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most of the popular React upload libraries were created nearly a decade ago. They're fantastic libraries, but they were built for a world where humans were the only consumers of documentation.&lt;/p&gt;

&lt;p&gt;Today, our documentation is read by both developers and AI agents.&lt;/p&gt;

&lt;p&gt;That changes how I think about open source.&lt;/p&gt;

&lt;h2&gt;
  
  
  React MediaDrop
&lt;/h2&gt;

&lt;p&gt;That thought became &lt;strong&gt;React MediaDrop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not because the React ecosystem needed another uploader, but because I wanted to experiment with what an AI-native open source library could look like.&lt;/p&gt;

&lt;p&gt;The library itself intentionally stays simple.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Headless by design.&lt;/li&gt;
&lt;li&gt;Lightweight.&lt;/li&gt;
&lt;li&gt;No styling opinions.&lt;/li&gt;
&lt;li&gt;A pluggable transport layer that isn't tied to any backend.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn't to compete with every upload library out there.&lt;/p&gt;

&lt;p&gt;The goal is to provide a clean foundation that you can extend.&lt;/p&gt;

&lt;p&gt;Today that means simple uploads.&lt;/p&gt;

&lt;p&gt;Tomorrow it could mean resumable uploads, multipart uploads, cloud-specific adapters, or completely custom transport implementations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation isn't just for humans anymore
&lt;/h2&gt;

&lt;p&gt;One thing I wanted to rethink was documentation.&lt;/p&gt;

&lt;p&gt;If developers increasingly use AI assistants to integrate libraries, then documentation should be discoverable and consumable by those assistants—not just by humans browsing a website.&lt;/p&gt;

&lt;p&gt;So the project was built with that philosophy from day one.&lt;/p&gt;

&lt;p&gt;The documentation is generated using &lt;strong&gt;&lt;a href="https://useblume.dev/" rel="noopener noreferrer"&gt;Blume&lt;/a&gt;&lt;/strong&gt;, another OSS project designed for both humans and AI.&lt;/p&gt;

&lt;p&gt;Beyond traditional docs, React MediaDrop also exposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;llms.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;AI-friendly documentation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://context7.com/autorender/react-mediadrop" rel="noopener noreferrer"&gt;Context7&lt;/a&gt; integration so agents can always discover the latest documentation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.skills.sh/autorender/react-mediadrop" rel="noopener noreferrer"&gt;Skills&lt;/a&gt; that can be added through &lt;code&gt;npx skills add autorender/react-mediadrop&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The idea isn't to replace documentation with prompts.&lt;/p&gt;

&lt;p&gt;It's to give AI agents structured knowledge so they're more likely to use the library correctly instead of guessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built for modern development workflows
&lt;/h2&gt;

&lt;p&gt;Whether you're:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prompting &lt;strong&gt;v0&lt;/strong&gt; to scaffold a React application,&lt;/li&gt;
&lt;li&gt;asking &lt;strong&gt;Claude Code&lt;/strong&gt; to integrate uploads,&lt;/li&gt;
&lt;li&gt;using &lt;strong&gt;Cursor&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;or writing every line yourself,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;the library should fit naturally into your workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking ahead
&lt;/h2&gt;

&lt;p&gt;React MediaDrop intentionally starts small.&lt;/p&gt;

&lt;p&gt;There's nothing revolutionary about uploading files.&lt;/p&gt;

&lt;p&gt;But I think there's room to rethink how libraries are built and documented for the next generation of software development.&lt;/p&gt;

&lt;p&gt;I'd love to see the project evolve with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;resumable uploads&lt;/li&gt;
&lt;li&gt;cloud storage adapters&lt;/li&gt;
&lt;li&gt;additional transport implementations&lt;/li&gt;
&lt;li&gt;community plugins&lt;/li&gt;
&lt;li&gt;richer AI skills&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;React MediaDrop is open source and already on npm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;code&gt;npm install react-mediadrop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/autorender/react-mediadrop" rel="noopener noreferrer"&gt;https://github.com/autorender/react-mediadrop&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href="https://mediadrop.dev" rel="noopener noreferrer"&gt;https://mediadrop.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hook is headless, so you own the markup. Here's the basic setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMediaDrop&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-mediadrop&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getRootProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getInputProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMediaDrop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;restrictions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/jpeg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;maxFiles&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And uploading with a pluggable transport, plus concurrency and retries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMediaDrop&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-mediadrop&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createXhrUploadTransport&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-mediadrop/xhr-upload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uploadAll&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMediaDrop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createXhrUploadTransport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/upload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;concurrency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Prefer a prebuilt component? Install via the shadcn registry
&lt;/h3&gt;

&lt;p&gt;No directory registration needed—it works today, straight from the repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm dlx shadcn@latest add autorender/react-mediadrop/dropzone
&lt;span class="c"&gt;# or&lt;/span&gt;
npx shadcn@latest add autorender/react-mediadrop/dropzone
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;React MediaDrop isn't trying to reinvent file uploads.&lt;/p&gt;

&lt;p&gt;It's an experiment.&lt;/p&gt;

&lt;p&gt;An experiment in building a React library that's lightweight, headless, extensible—and designed for a world where both humans and AI agents are first-class users.&lt;/p&gt;

&lt;p&gt;Maybe that's where open source is heading.&lt;/p&gt;

&lt;p&gt;I'd love to hear what you think.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>typescript</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
