Bharatvaj Hemanth
May 21, 2025
Many few things surprise me (in a good way that is), but the one that did was Airtable. When I was first introduced to this idea by my brother, my mind was blown out of the water. It was so simple and effective. Airtable gives a simple interface to understand/edit data without interacting with the code on the target product like web or application, designed to be used by non-technical creators like product owners.
Though Airtable and it's open-source alternative NocoDB presents a simple façade, it's backend functionality is not so simple which ultimately led me to search for alternatives. I was searching with keywords "simple Airtable", "nocode unix", "nocodb without server" and many such combinations over several sleepless nights, but without any fruition.
After pretty much sucking it up for over a year, I beleive I have come up with a solution (with minor caveats) I can live with. I present the Á la carte Airtable or Poor man's Airtable (based on the route you go), which is basically,
Á la carte Airtable is full of choices, but I hope I can provide some guidance to those choices and show my personal implementation of ALCAT.
I have a webdav server with ldap setup, so anyone who wants to access any file on the organization server, has to enter their credentials. Once that is done, organization users can access the csv files either through the "File Explorer" or through the web interface.
Enabling webdav is trivial to do in many web servers, this is how enable it in lighttpd without ldap,
# /etc/lighttpd/lighttpd.conf
$HTTP["url"] =~ "^/dav($|/)" {
alias.url = ("/dav" => "/srv/www/dav")
webdav.activate = "enable"
webdav.is-readonly = "disable"
webdav.sqlite-db-name = "/var/db/lighttpd/webdav.db"
dir-listing.activate = "enable"
dir-listing.show-readme = "enable"
## Use ldap if required ##
auth.require = ( "/dav" => (
"method" => "basic",
"realm" => "WebDAV",
"require"=> "valid-user"
))
}
Setting up ldap is not trivial, but there are good resources out there. I suggest reading LDAP for Rocket Scientists if you are a beginner, it is fun and easy to follow along.
If you feel that ldap is too much for you, you can use a simple authentication as shown above in the lighttpd example, more here.
And after all that we get streamlined file access.
I went with the simple route of using LibreOffice/Vim to edit csv files on the local WebDav folder, which on save gets saved on to the server.
There is also a slightly more complicated but better (for non-technical users) route which involves having an online editor and a style file.
Since I want things to be simple, I forked Projectcsv, simplified it and implemented the style feature. You can find it here.
Style file here is something that prettifies the table, for the user of csv editor (site/app owner) to improve the user experience of the csv editor. It does NOT affect the actual site/app.
As you may know, csv doesn't support styles but we can overcome this by storing the values in a separate style file.
To keeps things simple, for both the developer and user (the site/app owner), my convention is to have file-name.csv
css
for a corresponding file-name.csv
file.
In Projectcsv conveniently, the <table>
in the csv editor have class="row"
for rows and class="column"
for columns.
/* header color */
row[nth-child(1)] {
background-color: #eee;
}
/* rest of the row color */
row {
background-color: #ddd;
}
All I had to do in my implementation is just allow loading the style file that matches the csv's file name.
If you know a little bit css, you can understand how powerful this is. When loading the csv in the editor, just loading the style file along with it is enough to have a stylized preview.
Once all this is done, you have to sync the changes back to the website. This can take many form.
I basically run a awk script to generate m4 data from csv file that looks like this,
# generate.sh
awk -F',' 'printf "refill_book_card(`%s\047, `%s\047, `%s\047)\n", $1, $2, $3}' file-name.csv > refill-booking.html.in
and push it to the appropriate the appropriate html.in file which looks like this,
# The mismatched `' pair is not a mistake, it is just how m4 works.
refill_book_card(`https://www.amazon.in/hfc/bill/lpg', `/assets/icons/amazon.svg', `Amazon')
refill_book_card(`https://gpay.app.goo.gl/Org', `/assets/icons/gpay.svg', `Google Pay')
refill_book_card(`https://www.phonepe.com/', `/assets/icons/phonepe.svg', `PhonePe')
m4 has a lots of cons but saves me lot of headaches having to deal with webpack, nodejs, and other technologies, so don't judge me!
You can apply this with any technology. You have a CSV file, run a script on git hook/or sync and update the repo files.
Actually, organizations love this. Most of the enterprise software are overpacked software with "just incase" features, rightfully so in some case (ex: shipment software), but there are certain trenches in software that needs to be simple for it to effective and custom enough to tailor it to the organization. Airtable is one such case as it exists to reduce complexity not give options. Which makes ALCAT a good alternative.
If this feels too much, you should definitely consider using Airtable or NocoDB or other commercial solutions like Zoho Tables, because the benefits are enormous.
I'm pretty sure these methods are used by some people already in the wild, but I could not find any resource that could go into brief detail. So I posted it as a resource. Have fun!