What I built
I built tmp.spacet.me, a web-based local file storage application. Basically, you can put files into it, and you can get files out of it. It aims to support every possible methods that browsers allow web apps to work with files.
It also comes with an extensions system. Users can add extensions to enhance the functionalities of the app. The goal is to improve operability between web-based applications that work with files.
For example, the tmp-webrtc extension lets me send files from one device to another using peer-to-peer technology WebRTC.
The tmp-photopea extension lets me edit image files in Photopea.
Users can build their own extensions to suit their needs.
For example, I built an extension to upload images to my static file hosting.
Although tmp.spacet.me is built using React and Next.js, this is just an implementation detail and extension authors don’t need to know any React. That’s because extensions run on their own page and communicate with tmp.spacet.me via the postMessage
API only.
Category Submission
Random Roulette
App Link
https://tmp.spacet.me/
Screenshots
Description
A web-based local file storage. You can put files into it, and you can get files out of it. More functionalities can be added through extensions.
Link to Source Code
tmp.spacet.me
tmp.spacet.me is a web-based local file storage application. Basically, you can put files into it, and you can get files out of it. It aims to support every possible methods that browsers allow web apps to work with files.
It also comes with an extensions system. Users can add extensions to enhance the functionalities of the app.
For example, the tmp-webrtc extension lets me send files from one device to another using peer-to-peer technology WebRTC.
The tmp-photopea extension lets me edit image files in Photopea.
Users can build their own extensions to suit their needs.
For example, I built an extension to upload images to my static file hosting.
For more information, including the Extensions API, take a look at the documentation.
Devlog
This project is participating in the DigitalOcean App Platform Hackathon on DEV and is deployed to DigitalOcean® App Platform as a static site.
Permissive License
All code is MIT Licensed
Background
There are so many great web-based tools. From Markdown editors to file sharing services to diagramming tool to design tool to image editor and compressor to voice and screen recorder to myriad of cloud storage services, etc.
Many of these tools work with files. But they tend to be its own silo and do not interoperate with other tools.
There has been attempts to solve this from the web platform side. There was an experimental Web Intents API which failed. More recently, there are also the Web Share API and the Web Share Target API which integrates natively with the system’s Share dialog. Unfortunately Desktop devices don’t have them and so it’s only available on Android right now.
So, as I become more reliant on web-based tools, I want to try my take at a userland solution. So the missing piece, I think, is a central hub, where files can be sent to, which would then be forwarded to other web-based app or saved to disk. I want it to have an extension system, so anyone can build more integrations without having to modify the main app. Furthermore, deeper integrations with existing web-based apps can be implemented via browser extensions.
How I built it
For the main app, tmp.spacet.me
, I used DigitalOcean App Platform to host the app, which is a static web application. The main application is built using React and Next.js. Deployment to DigitalOcean App Platform is very straightforward and I’m impressed by how easy it is to set up. I’m looking forward to support for deployment previews in the future.
For the extension system, when the extension URL is entered, the main app fetches the manifest file, which contains the information about the extension, as well as which file types can be handled. Then, when the extension is activated, it opens a separate browser window and communicate with the main app via a JSON-RPC-based protocol. This gave me opportunities to put cross-site messaging and micro-frontend concepts into practice.
For the tmp-webrtc
extension, at first I wanted to create a backend service to implement peer discovery. That would also give me an opportunity to try out DigitalOcean’s paid services (like running backend apps and using a managed database). Unfortunately due to time constraints I didn’t get around to doing that and used the P2PT library for peer discovery instead. P2PT uses public WebTorrent trackers as a WebRTC signaling server, and so no backend services have to be deployed. So it ended up being another static app. This is my first time using P2PT and WebRTC for file transfers though, so I still think I learned a lot.
I really like that DigitalOcean’s App Platform makes setting up CORS very straightforward (can be set up via the console), while Netlify, Vercel requires creating a configuration file. Having CORS is crucial for the extension system to work, because tmp.spacet.me
needs to fetch the manifest file to discover the extension's functionalities.
The tmp-webrtc
extension is built using Vue 3 and Vite. I have never used Vite before, so that’s another thing I learned. By the way, I don’t like running commands to generate new projects, so I took the opportunity to shave that yak, and created the Fresh App Factory.
I also used other other cloud services other than DigialOcean. The documentation site is just a Jekyll site hosted on GitHub Pages, which I chose for simplicity. I like that DigitalOcean App Platform allows multiple static apps (or “components”) to be hosted on the same domain, but I could not get Jekyll to work on it.
The application’s UI is not polished at all and could use a lot of improvements. But I think it’s good enough for a proof-of-concept. Since I started building this, I have been using it a lot in my own personal workflow. Sending pictures and videos between my 4 devices, now I just use tmp.spacet.me.
Some areas for future improvements include:
- Improving the user experience, accessibility and performance.
- Allowing files to be stored temporarily in the in-memory storage first before committing to PouchDB.
- Allowing other web apps to directly
postMessage
to tmp.spacet.me (without an extension), reducing the irony.
I hope you find the tool useful, and thanks for reading!