<?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: Obakeng Mosadi (Baki)</title>
    <description>The latest articles on DEV Community by Obakeng Mosadi (Baki) (@bakimosadi).</description>
    <link>https://dev.to/bakimosadi</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%2F2832971%2F638556a6-ccd4-473e-b892-7694c96f10cd.png</url>
      <title>DEV Community: Obakeng Mosadi (Baki)</title>
      <link>https://dev.to/bakimosadi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bakimosadi"/>
    <language>en</language>
    <item>
      <title>Why I Built An Open Source Alternative To WeTransfer</title>
      <dc:creator>Obakeng Mosadi (Baki)</dc:creator>
      <pubDate>Mon, 07 Sep 2026 16:31:15 +0000</pubDate>
      <link>https://dev.to/bakimosadi/why-i-built-an-open-source-25f4</link>
      <guid>https://dev.to/bakimosadi/why-i-built-an-open-source-25f4</guid>
      <description>&lt;p&gt;During university I was sending photo sets to clients most weeks. I'd zip them up, upload them to Google Drive and send a link.&lt;/p&gt;

&lt;p&gt;It worked for me for the most part. But my client files sat in the same drive as everything personal I owned, and the link I sent looked like nothing that had to do with my work.&lt;/p&gt;

&lt;p&gt;Then I found WeTransfer (I think I might've stumbled on it on social media at the time). Upload, enter an email, send and that was it. It felt like handing someone the work rather than filing it somewhere, and that difference turned out to matter more to me than any feature either product had.&lt;/p&gt;

&lt;p&gt;Nine years later I built Campsend, an open-source, self-hostable version of that. Rails 8 and SQLite.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Changed My Mind About Ownership
&lt;/h3&gt;

&lt;p&gt;In 2025 WeTransfer updated its Terms of Service. The new wording covered what they could do with uploaded content, including machine learning use, and enough people read it the same way that WeTransfer &lt;a href="https://wetransfer.com/blog/story/wetransfer-terms-of-service-changes-july-2025" rel="noopener noreferrer"&gt;changed it back within a week&lt;/a&gt;. And for me, that raised a bunch of questions.&lt;/p&gt;

&lt;p&gt;Who controls the files I send? What happens when the pricing changes, or the business model does? And what happens when I already have a bucket and want the files to land in it?&lt;/p&gt;

&lt;p&gt;I wanted that delightful sending experience that WeTransfer gave me without handing over the storage layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the Existing Options Didn't Fit
&lt;/h3&gt;

&lt;p&gt;I looked at what was already out there. &lt;a href="https://masv.io/" rel="noopener noreferrer"&gt;MASV&lt;/a&gt; is hosted, so it has the same problem. &lt;a href="https://erugo.app/" rel="noopener noreferrer"&gt;Erugo&lt;/a&gt; self-hosts, but it feels like a super file sharing app that still didn't feel like a nice file sharing experience.&lt;/p&gt;

&lt;p&gt;They're solving real problems. &lt;/p&gt;

&lt;p&gt;Mine is smaller and more opinionated: Send work to a client, make the delivery look like mine, keep the files where I put them.&lt;/p&gt;

&lt;p&gt;That's all.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Campsend Does
&lt;/h3&gt;

&lt;p&gt;You send files, brand the delivery page, see whether the recipient opened or downloaded it and choose where the files are stored. You can also run the whole thing yourself and point it at your own object storage.&lt;/p&gt;

&lt;p&gt;Self-hosting was the part I cared about most, which meant the app had to be simple to operate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Rails 8 and SQLite
&lt;/h3&gt;

&lt;p&gt;Rails 8 went in the direction I needed: fewer moving parts to stand up before the app runs. I didn't want self-hosting Campsend to mean provisioning a queue, a cache, a session store and a Postgres cluster first. I wanted one application, one database, object storage and a deploy.&lt;/p&gt;

&lt;p&gt;SQLite fits that need. Campsend is built around a single writable host.&lt;/p&gt;

&lt;p&gt;I've load tested it on a laptop: 200 concurrent users, 72 requests a second, 3.3 deliveries created a second, and a p95 of 36ms measured at the server. SQLite never hit lock contention once. What I ran out of first was Puma threads, not database. (I could end being proven wrong here but I think for most use cases, it will work).&lt;/p&gt;

&lt;h3&gt;
  
  
  Two Things I Didn't Expect
&lt;/h3&gt;

&lt;p&gt;The first was the storage bill. Cloudflare R2 charges &lt;a href="https://developers.cloudflare.com/r2/pricing/" rel="noopener noreferrer"&gt;$0.015 per GB per month&lt;/a&gt; with no egress fee; S3 charges &lt;a href="https://aws.amazon.com/s3/pricing/" rel="noopener noreferrer"&gt;$0.023&lt;/a&gt; plus $0.09 per GB out. Sending 100GB to clients in a month costs $2.30/month on S3 and $1.35/month after R2’s free 10 GB. Almost none of what you pay a file-sharing service is storage. It's the product around it.&lt;/p&gt;

&lt;p&gt;The second was how little I had to build. Authentication, email, background jobs, database access and file storage were already there, so most of my time went into the delivery experience instead of the plumbing.&lt;/p&gt;

&lt;p&gt;Which turned out to be the interesting part. File sharing and file management are different jobs, and only one of them needs a folder structure.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmec4afi0pjhzxvxlpnim.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmec4afi0pjhzxvxlpnim.png" alt="Campsend preview of a file being sent to a user" width="800" height="733"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;I'm writing up how to self-host Campsend, and the SQLite post above. Try it at &lt;a href="https://campsend.app/files" rel="noopener noreferrer"&gt;Campsend&lt;/a&gt; or &lt;a href="https://github.com/obakeng-develops/campsend" rel="noopener noreferrer"&gt;read the source&lt;/a&gt; on GitHub. Issues and pull requests welcome.&lt;/p&gt;

&lt;p&gt;Everyone's building storage platforms. I want a beautiful file sharing experience.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>rails</category>
      <category>selfhosted</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
