$ \ifdefined\HCode % we are running tex4ht % don't load the physics package \require{physics} % \require{siunitx} \else % we are running LaTeX % \usepackage{physics} \fi \renewcommand{\phi}{\varphi} \renewcommand{\epsilon}{\varepsilon} \newcommand\define[1]{\textbf{#1}\index{#1}} % Letters/Font \DeclareMathOperator{\bF}{\mathbb{F}} \DeclareMathOperator{\bQ}{\mathbb{Q}} \DeclareMathOperator{\bZ}{\mathbb{Z}} \DeclareMathOperator{\bR}{\mathbb{R}} \DeclareMathOperator{\bC}{\mathbb{C}} \DeclareMathOperator{\bE}{\mathbb{E}} \DeclareMathOperator{\bN}{\mathbb{N}} \DeclareMathOperator{\bM}{\mathbb{M}} \DeclareMathOperator{\bH}{\mathbb{H}} \DeclareMathOperator{\bP}{\mathbb{P}} \DeclareMathOperator{\cH}{\mathcal{H}} \DeclareMathOperator{\cA}{\mathcal{A}} \DeclareMathOperator{\cB}{\mathcal{B}} \DeclareMathOperator{\cC}{\mathcal{C}} \newcommand\bb[1]{\mathbb{#1}} \newcommand\mc[1]{\mathcal{#1}} \newcommand{\w}[1]{\wedge#1} \newcommand\mean[1]{\bar{#1}} \newcommand\conj[1]{\bar{#1}} \DeclareMathOperator*{\argmin}{arg\,min} \DeclareMathOperator*{\argmax}{arg\,max} % Grouping Operators \newcommand{\floor}[1]{\left\lfloor#1\right\rfloor} \newcommand{\ceil}[1]{\left\lceil#1\right\rceil} \newcommand{\parens}[1]{\left(#1\right)} % note that we defined bracks not brace/braces because brace is already used by amsmath \newcommand{\bracks}[1]{\left\{#1\right\}} \newcommand{\sqbracks}[1]{\left[#1\right]} \newcommand{\clop}[1]{\left[#1\right)} \newcommand{\opcl}[1]{\left(#1\right]} \newcommand{\angles}[1]{\langle#1\rangle} \newcommand{\p}[1]{\left(#1\right)} % \newcommand{\b}[1]{\left\{#1\right\}} \newcommand{\q}[1]{\left[#1\right]} \newcommand{\abs}[1]{\left|#1\right|} \newcommand{\n}[1]{\left\lVert#1\right\rVert} % probability \DeclareMathOperator{\Cov}{Cov} \DeclareMathOperator{\Var}{Var} \DeclareMathOperator{\Cor}{Cor} \DeclareMathOperator{\median}{median} % https://tex.stackexchange.com/questions/154530/resolved-a-conditional-independence-symbol-that-looks-good-with-mid \newcommand{\ind}{\mathrel{\text{\scalebox{1.07}{$\perp\mkern-10mu\perp$}}}} % or \newcommand{\ind}{\perp\!\!\!\!\perp} % now included in the physics package %\newcommand{\norm}[1]{\left\lVert#1\right\rVert} \DeclareMathOperator{\Bias}{Bias} \DeclareMathOperator{\Range}{Range} % linear algebra \DeclareMathOperator{\nullity}{nullity} \DeclareMathOperator{\rowrank}{row rank} \DeclareMathOperator{\colrank}{column rank} % now in the physics package % \DeclareMathOperator{\tr}{Tr} % \DeclareMathOperator{\Tr}{Tr} \DeclareMathOperator{\perm}{perm} \DeclareMathOperator{\GL}{GL} \DeclareMathOperator{\SL}{SL} \DeclareMathOperator{\imm}{imm} \DeclareMathOperator{\poly}{poly} \DeclareMathOperator{\Lie}{Lie} \DeclareMathOperator{\Cl}{Cl} \DeclareMathOperator{\Span}{span} \DeclareMathOperator{\Int}{int} \DeclareMathOperator{\adj}{adj} % abstract algebra \DeclareMathOperator{\Aut}{Aut} \DeclareMathOperator{\id}{id} \DeclareMathOperator{\Id}{Id} \DeclareMathOperator{\Inn}{Inn} \DeclareMathOperator{\irr}{irr} \DeclareMathOperator{\Frac}{Frac} \DeclareMathOperator{\Frob}{Frob} % category theory \DeclareMathOperator{\ob}{ob} \DeclareMathOperator{\Set}{Set} \DeclareMathOperator{\Grp}{Grp} \DeclareMathOperator{\Ring}{Ring} \DeclareMathOperator{\Top}{Top} \DeclareMathOperator{\Vect}{Vect} \DeclareMathOperator{\End}{End} \DeclareMathOperator{\Hom}{Hom} \DeclareMathOperator{\im}{im} % \DeclareMathOperator{\Vec}{Vec} \DeclareMathOperator{\Rel}{Rel} \DeclareMathOperator{\Mon}{Mon} \DeclareMathOperator{\Pre}{Pre} \DeclareMathOperator{\SRel}{SRel} \DeclareMathOperator{\Ab}{Ab} \DeclareMathOperator{\Perm}{Perm} \DeclareMathOperator{\Nat}{Nat} \DeclareMathOperator{\Cat}{Cat} % now in physics package % \DeclareMathOperator{\op}{op} \DeclareMathOperator{\FinStoch}{FinStoch} \DeclareMathOperator{\Stoch}{Stoch} % number theory \DeclareMathOperator{\rad}{rad} \DeclareMathOperator{\Disc}{Disc} \DeclareMathOperator{\res}{res} \DeclareMathOperator{\lcm}{lcm} % differential geometry \DeclareMathOperator{\Man}{Man} \DeclareMathOperator{\supp}{supp} \DeclareMathOperator{\Diff}{Diff} \DeclareMathOperator{\VB}{VB} % complexity theory \DeclareMathOperator{\fspace}{FSPACE} \DeclareMathOperator{\sspace}{SPACE} \DeclareMathOperator{\pspace}{PSPACE} \DeclareMathOperator{\AR}{AR} \DeclareMathOperator{\MA}{MA} \DeclareMathOperator{\B}{B} \DeclareMathOperator{\ARMA}{ARMA} \DeclareMathOperator{\diag}{diag} \DeclareMathOperator{\IMA}{IMA} \DeclareMathOperator{\ARIMA}{ARIMA} \DeclareMathOperator{\Vol}{Vol} \DeclareMathOperator{\essup}{essup} \DeclareMathOperator{\essinf}{essinf} \DeclareMathOperator{\Bernoulli}{Bernoulli} \DeclareMathOperator{\Law}{Law} \DeclareMathOperator{\Normal}{Normal} \DeclareMathOperator{\Geometric}{Geometric} \DeclareMathOperator{\Poisson}{Poisson} \DeclareMathOperator{\Uniform}{Uniform} \DeclareMathOperator{\Beta}{Beta} \DeclareMathOperator{\TV}{TV} \DeclareMathOperator{\io}{i.o.} \DeclareMathOperator{\ale}{a.e.} \DeclareMathOperator{\as}{a.s.} \DeclareMathOperator{\iid}{i.i.d.} % least fixed point \DeclareMathOperator{\lfp}{lfp} \DeclareMathOperator{\sign}{sign} \DeclareMathOperator{\pval}{p.v.} \DeclareMathOperator{\sgn}{sgn} \DeclareMathOperator{\dom}{dom} \DeclareMathOperator{\Ran}{Ran} \DeclareMathOperator{\Hol}{Hol} \DeclareMathOperator{\cl}{cl} \DeclareMathOperator{\Pol}{Pol} \DeclareMathOperator{\sinc}{sinc} \DeclareMathOperator{\E}{\mathbb{E}} \DeclareMathOperator{\Pr}{\mathbb{P}} \DeclareMathOperator{\R}{\mathbb{R}} $

Offline software suggestions

Published: 19 Dec 2024

Last updated: 26 Jun 2025

Categories Tags

Offline software suggestions

I spent a lot of time in 2024 switching to offline-first apps, and I’d like to share my top choices to save others some time. By offline-first, I mean apps workflows that minimize online requirements. There are two high-level software choices I made. First, I handle syncthing between devices through Syncthing. Second, I use Obsidian to handle working with Markdown files for many notes, and I record data like fitness data and book notes in Markdown files. If you have additional questions about my choices below or things to try, send me a note! I have additional notes not included here that I might add later on things like active GitHub issues that, if resolved, would shift my rankings.

Syncthing enables working across desktop & mobile

A tool like Syncthing in indispensable to sync data like

Rsync also works, but Syncthing has the advantage of being able to scan on your local network dynamically (as well as globally if you enable that). This is useful on network configurations when accessing other devices directly via IP doesn’t work, and because it can be cumbersome to have to manually update IPs when you switch networks. Also, keep in mind that you can sync over your phone’s hotspot with tethering

Obsidian enables simple data storage

I find it unfortunate that there isn’t really a good open source solution to notes, but I have found Obsidian significantly better than the alternatives like Logseq, Dendron, Foam, and Zettlr. I don’t like the forced outlining in Logseq, Dendron’s development is discontinued, Foam didn’t have as many features, and Zettlr doesn’t support as much LaTeX code since it uses KaTeX instead of MathJax. Obsidian + Emacs for certain kinds of edits works great. I also use Obsidian to handle tasks rather than CalDAV/Thunderbird. I like putting tasks on notes they’re semantically related to, such as project notes, and them gathering them onto organizational notes with the Tasks plugin.

Photos and Obsidian

I like to have my photo library accessible to Obsidian, as then I can:

On Linux, one can achieve this with a symlink in a directory in the Obsidian vault. On Android, one must actually place the entire photo directory (synced with Syncthing) under the directory. This is because Android doesn’t allow symlinks between two directories in the main storage space.

Plant taxonomy in Obsidian instead of only using iNaturalist

I create Obsidian notes for species I’ve observed and verified with iNat and include data about them in the YAML properties. I have a script to build a CSV from this data that I import into Anki for learning genera and family names from photos. I might write another post about this later.

Books

I used Goodreads before. Instead, now I just create a Markdown note for each book, tag it as “to-read”, and use an Obsidian Dataview script to show all the books I’d like to read.

Fitness data

I make a line in my daily markdown note recording info about the workout, and I have a separate script to parse these and compile data displays like Strava has.

Many other types of software

There are a bunch of other assorted suggestions I have that I listed below along with reasoning. The majority of apps I use are open source, but there are a couple of cases where the closed source options are much better than the competition; I marked those with a “(CS)”. I annotated each suggestion with “(L)” for Linux or “(A)” for Android.

Moving to the suggestions above

How to convert OneDrive notes to Obsidian

It’s challenging to export OneDrive notes to a portable framework, and the best way is unfortunately install Windows, download the full version of OneDrive, and then export your notes as a PDF. Also, save it as a onepkg file for the sake of preservation. It doesn’t seem easy to get nice SVGs for your notebooks that can be imported elsewhere.

Moving favorites from Google Maps to GPX

I used Google Maps before. The portable way to handle locations, though, is to save them as a GPX file that you can import/export with apps like OSMAnd. I mentioned I use Organic Maps more now for daily searching, but I haven’t yet ported my saved locations from OSMAnd to Organic Maps— I’m not sure if Organic Maps can import and export GPX (or KML, etc.), but doing that would be ideal.

Google Maps is quite difficult to export from. Google My Maps lets you export GPX or KML directly, if I remember correctly, but standard Google Maps does not. The best solution if you have a large number of files is to have an LLM write a script with the Google Maps API to save them as a GPX file.