more compat testing
trim ntry page POST
compat
minimal HTML4 journalling program, written in golang
features:
I wrote this so I could edit my journal (a text file) from multiple computers. it is basically a system for versioning and editing sections of a specially-formatted text file
$ git clone https://git.amehut.dev/~aleteoryx/webjrnl
$ cd webjrnl
$ go build -ldflags '-w -s'
$ mkdir db
$ echo -n 'changeme' | sha1sum
fa9beb99e4029ad5a6615399e7bbae21356086b3 -
$ echo '[{"id": "marmalade", "passhash": "fa9beb99e4029ad5a6615399e7bbae21356086b3"}]' >db/users.json
$ ./jrnl :8080 db
initialized!
this is untested in go versions < 1.24.5. if you successfuly compile it in an earlier version, let me know and I will update go.mod. it has been tested on linux, but should have no problems running on other unixes, plan 9, or even windows.
webjrnl is a single executable, jrnl. it takes 2 arguments: the address
on which to listen, and the database location. if the second argument
is omitted, it is assumed to be .
if you plan to run webjrnl behind a reverse proxy, pass it the -proxied flag. this will tell it to read the X-Forwarded-For header when writing logs.
the database has the following layout:
db/
users.json - the list of users
{userid}/{year}/{month}/{day}/ - the entry for a given date
latest - contains the ID of the latest edit, in base 10
{id} - the full text of edit id
users.json contains an array, each element of which corresponds to a jrnl. it must contain id and passhash. the former is the jrnl username, the latter is the SHA-1 hash of the user's password. it may also contain a timezone field, the value of which should be an IANA time zone name, like "UTC" or "America/New_York". this timezone is used when displaying dates in the UI.
users.json is read once, at startup. if you modify it, you will need to restart the service.
no caching of the database is performed. for a performant experience, make sure your kernel is configured to cache the database directory in RAM.
webjrnl is written in such a way that multiple instances can be pointed to the same database, and access it concurrently without risk of corruption.
for convenience, an openrc script is included at /openrc. edit it to your needs.
jrnl text is mostly free-form ASCII text, delimited by lines of the
form > YYYY-MM-DD. in any text box accepting jrnl text, you may
insert such a line anywhere to start a new entry. webjrnl will sort it
into reverse chronological order, once it is submitted.
webjrnl does not delete anything. when an entry is edited, the new text is saved as the latest revision. it is not possible to delete an entry or revision, without hand-editing the database.
a typical jrnl excerpt looks something like:
> 2026-04-26
= 1725, cafe =
got webjrnl mostly together, just need to write the docs.
...
> 2026-04-25
= 1020, desk =
I'm SO EXCITED for today!!!
...
the homepage, /dash, has links to a list of entries, an import tool, a backup tool, and each year's page. if there is no entry for today or yesterday, buttons to create them are also presented.
the import tool accepts jrnl text, and populates the database with it. the backup tool exports the entire database as jrnl text, including all revisions. it can be accessed programatically at /save?download
year pages are populated with the jrnl text for a given year, and have a menu to navigate to an entry's page. this is intended as the primary editing frontend.
entry pages allow you to change an entry's text, and contain a list of previous revisions. this is not jrnl text, and does not parse date headings. if you include one, it may lead to unexpected results the next time the entry is parsed as part of jrnl text
some. in particular, POST requests from a different Referer or Origin
are blocked, as are all javascript requests from different sites,
assuming the browser supports the Sec-Fetch-* set of headers
HTTP basic authentication is very much so insecure over an unencrypted connection.
the contents of the database are stored in plaintext.
needs testing:
works, no notes:
works with caveats:
doesn't work: