HN user

thecodrr

548 karma

Building Notesnook: https://notesnook.com

Posts57
Comments151
View on HN
blog.notesnook.com 9mo ago

Notesnook and Kagi are partnering up

thecodrr
2pts0
muelsyse.codeberg.page 1y ago

Been Busy

thecodrr
2pts0
blog.notesnook.com 1y ago

It's time to leave Bitwarden (2023)

thecodrr
19pts9
blog.notesnook.com 2y ago

Show HN: Notesnook v3 is here with note linking, at rest encryption and more

thecodrr
3pts1
ronjeffries.com 2y ago

Do the simplest thing that could possibly work (1998)

thecodrr
1pts0
sensor.fyi 2y ago

Mouse Guide

thecodrr
2pts0
en.wikipedia.org 2y ago

Fabrice Bellard

thecodrr
3pts4
www.amplenote.com 2y ago

Amplenote's “Note Decryption” Policy

thecodrr
2pts0
transfer.sh 2y ago

Easy File Sharing from the Terminal

thecodrr
2pts0
chriscoyier.net 3y ago

MDN Has Ads Now

thecodrr
4pts0
kate-editor.org 3y ago

Integrated Terminal on Windows in KDE Kate

thecodrr
3pts1
github.com 3y ago

Contour Terminal – A Modern and Cross-Platform C++ Terminal Emulator

thecodrr
3pts1
blog.notesnook.com 4y ago

Adding 2FA in Notesnook

thecodrr
1pts0
blog.notesnook.com 4y ago

NeutralinoJS: The Next Best Alternative to Electron and Tauri?

thecodrr
1pts0
blog.notesnook.com 4y ago

React useRef

thecodrr
2pts0
blog.streetwriters.co 4y ago

Why Is Philosophy Important?

thecodrr
1pts0
blog.notesnook.com 4y ago

React Native JSI: Part 2 – Converting Native Modules to JSI Modules

thecodrr
1pts0
blog.notesnook.com 4y ago

Are we ready for a world without privacy of data?

thecodrr
3pts0
blog.notesnook.com 5y ago

Notesnook v1.4.1 – A private notes alternative to Evernote

thecodrr
2pts0
monograph.notesnook.com 5y ago

Greetings from The Illuminati (world elite empire)

thecodrr
1pts0
blog.notesnook.com 5y ago

Getting Started with React Native JSI Modules

thecodrr
4pts0
blog.notesnook.com 5y ago

Notesnook v1.4: private note publishing and a yearly plan

thecodrr
3pts0
blog.notesnook.com 5y ago

Notesnook: A Private Note Taking Alternative to Evernote

thecodrr
11pts11
github.com 5y ago

Notesnook v1.3.6

thecodrr
1pts0
github.com 5y ago

Fdir 5.1.0

thecodrr
2pts0
rnmmkv.vercel.app 5y ago

Show HN: I built the fastest encrypted storage for React Native using JSI(C++)

thecodrr
6pts0
github.com 5y ago

MDN yari is now using fdir for 10x performance gains

thecodrr
2pts0
notesnook.com 5y ago

Show HN: Notesnook – A cross-platform privacy focused zero-knowledge notes app

thecodrr
32pts43
blog.streetwriters.co 5y ago

Overcoming boredom while writing

thecodrr
1pts0
blog.streetwriters.co 5y ago

How to Write Good Sentences

thecodrr
1pts0

Benchmarking is a mess everywhere. Sure you can get some level of accuracy but reproducing any kind of benchmark results across machines is impossible. That's why perf people focus on things like CPU cycles, heap size, cache access etc instead of time. Even with multiple runs and averaged out results you can only get a surface level idea of how your code is actually performing.

React is not slow. React is not "big". React is not the reason your website is slow.

Any engineer who thinks that its React that is causing the slow renders and replacing it with X is deluded. Yes, there are ways to make slow React web apps. But there are also ways to make fast React web apps. It just requires effort and a little bit of foresight.

You'd already be using source maps in any real-world scenario so I am not sure what's the value proposition here outside of "just for fun, I guess".

The tsc transpilation to lower ES versions is actually really useful when using not-so-recent Node versions. Not to mention this severely restricts TypeScript syntax to "just types" which isn't too bad but it means you now have to worry about yet another thing.

Then there's the ESM & CJS mess. You almost always want to export in both formats which will change a lot of the syntax, so this quickly falls apart for anything serious.

Just use esbuild if you want speed.

Hello everyone!

After around 2 years, we are back on HN with a massive update for Notesnook. But before that, here's a short introduction:

Notesnook is an end-to-end encrypted, 100% open source [0] note taking app that prioritizes user privacy.

v3 brings a lot of really radical changes, such as:

- Migration to SQLite

- At rest encryption

- Note linking

- Nested notebooks

- App lock on all platforms

You can read more about all these here: https://blog.notesnook.com/introducing-notesnook-v3/

Our goal with Notesnook has always been to make privacy simpler to adopt for normal users who don't have time to think about privacy. We do that by making privacy that "default" everywhere in the app. We recently crossed 100K registered users with over 4 million notes created on our platform.

If anyone has any questions I'd be happy to answer.

[0] https://github.com/streetwriters/notesnook/

There's no point in offering users self hosting if you are going to throw them into a fire by doing so. Notesnook is rapidly evolving and changing, and hoping for self hosted users to keep up is impractical. Instead, we want to first stabilize the backend, and then think about self hosting.

After v3, our primary focus will be on self hosting and getting an audit done.

It seems to me you are looking for a syntax highlighter in a note taking app. Which modern language are you looking for?

There are encrypted backups. Actually, backups are encrypted by default.

Notesnook also works offline by default so there's no need for a special mode. It's also, obviously, local-first since everything gets encrypted on your device. We don't have a lot of options there.

What "might be better" in the editor?

Obsidian is a cool app but it's targeted for a very specific kind of user. Of course, for a technical user Obsidian would feel like home but for an average user with not a lot of technical know how, Obsidian would go way over their heads. Not everyone appreciates having to handle files, worry about syncing, security etc.

Oh wow. Just heard the Notesnook is on the front page of HN. I am the co-founder so if you have any questions, feel free to ask.

Oh and to clear a few confusions:

1. Notesnook is 100% open source. That includes the server, client apps, and everything else. It's not partially open source.

2. Zero knowledge does not mean Zero Knowledge Proof but Zero Knowledge as in we, the company and people behind Notesnook, have no knowledge regarding what you have in your notes. I see that this might be more accurately called "no knowledge".

Ah war stories.

Just a few weeks back a user came to us after failing to migrate GBs of their data off of Evernote. This, of course, included attachments. They had successfully imported & synced 80K items, but when they tried to login on their iPhone, the sync was really, really slow. They had to wait 5 hours just to get the count up to 20K items. And that's when the app crashed resetting the whole sync progress to 0.

In short, we had not considered someone syncing 80K items. To be clear, 80K is not a lot of items even for a local-first sync system, but you do have to optimize for it. The solution consisted of extensively utilizing batching & parallelization on both the backend & the users' device.

The result? Now their 80K items sync within 2 minutes.

I don't think even you understand what you just said.

Consumer devices are notorious for their reliability problems. Compared to a full blown server that you have 100% control over with almost insane amounts of RAM & CPU power & a lot of guarantees.

Running a migrations on a server is far, far different to running it on every users' device. The sheer scale of it is different.

Using 4 GB per user on your backend works?

That was a comment on the average RAM on a consumer device - not the total RAM required per user.

I think you misunderstand. My intention was not to say local-first is bad or impossible; it's not. We have been local-first at Notesnook since the beginning and it has been going alright so far.

But anyone looking to go local-first or build a local-first solution should have a clear idea of what problems can arise. As I said in the original comment: it's not all gardens and roses.

As someone who has been doing local-first for the last 3 years with Notesnook, let me tell you: it's not all gardens and roses. Local first has its own very unique set of problems:

1. What to do with stale user data? What happens if a user doesn't open the app for a year? How do you handle migrations?

2. What about data corruption? What happens if the user has a network interruption during a sync? How do you handle partial states?

3. What happens when you have merge conflicts during a sync? CRDT structures are not even close to enough for this.

4. What happens when the user has millions of items? How do you handle sync and storage for that? How do you handle backups? How do you handle exports?

One would imagine that having all your data locally would make things fast and easy, but oh boy! Not everyone has a high end machine. Mobiles are really bad with memory. iOS and Android have insane level of restrictions on how much memory an app can consume, and for good reason because most consumer mobile phones have 4-6 gbs of RAM.

All these problems do not exist in a non-local-first situation (but other problems do). Things are actually simpler in a server-first environment because all the heavy lifting is done by you instead of the user.

I don't think that's true. We have been using ASP .NET Core + SignalR for everything in Notesnook[0]. It has great performance, libraries for everything out there, very good ergonomics, and a mature ecosystem.

I know you can probably get more performance out of Rust or Go but I don't think rq/s benchmarks really hold up in reality. If you are running a startup, you'd probably see 1 to 2 rq/s unless you become viral. .NET Core can easily handle that and more.

[0] https://notesnook.com

The author is going into technicalities without much actual substance, ending with: it depends.

I think whenever we, as programmers, try to pin down a certain principle, it bites us. Hard. DRY was cool as an observation but when it got turned into a law we saw the spaghetti code.

Duplication, on the other hand, is detested almost as much as the goto statement. Let me tell you, it's not that bad. Duplicate code makes everything more flexible. It helps you to NOT bend over backwards in order to change a line of code. It allows you to NOT touch anyone else's code.

So many good things. Of course, I agree with the author's summary of the bad things that can happen with duplicated code. But there's a litmus test for that:

If you have to make changes in multiple blocks of duplicated code in order to change the behavior of something, there's a problem. DRY out the code so you only have to touch 1 place.

If, however, 2 blocks of code LOOK similar but aren't actually the same, and changing one block doesn't make the other block outdated and stale, you are good to go.

Judge and decide. It's just 2 approaches that when taken to an extreme can cause a lot of pain, but if used with common sense, nothing is simpler.

Anyone who says X must be done in Y way is most absolutely wrong. Who is Tiago Forte to tell how I should organize my thoughts? Am I a robot to follow so simply in the footsteps of another? I would like a more general approach, please.

Any serious note taker eventually realizes that the way their brain works doesn't really fit into any PARA, ARPA or any other standarized system.

Note taking is a messy business. It's not supposed to be organized because you take notes to become more organized, not to organize more notes.

Just take your notes.

Organization will automatically happen. Humans are very bad at doing things randomly. There's always an order, a sequence, a method to the way we do things. Who's to say your method is better than mine?

I think all note apps are just databases. Some day an LLM might be able to make sense of the messy notes in my note taking app but I am not holding my breath. My notes are not supposed to stand the test of time. They are ephemeral thoughts relevant only for a specific period - a best-worst case against the risk of forgetting them.

The most an AI should do is find relevant notes on a topic I search. That's it. I don't need its robotic voice summarizing my grotesque ideas in a painless, unpassionate way. The last thing I need is more of my ideas seeping into more of my computers in hopes of somehow making me smarter.

These guys also tried to submit PRs on the Notesnook[0] repository. The PRs are really good but there's no way to talk to the actual developer working behind those PRs. They have a single central account named "gitstart" and all PRs that any of their user works on falls under that account. Of course, we couldn't accept PRs from them because they don't follow DCO[1] i.e., DCO requires that the committer MUST NOT be an organization.

I talked to them about this and they said they'd work on it etc. etc. Not sure if anything has changed in that regard or not.

[0] https://github.com/streetwriters/notesnook

[1] https://developercertificate.org/

I would NOT call this frugal at all, actually. You are overspending in a lot of places and under spending in others. $281.32 per month for such a simple service is...astonishing. Change Vercel and Intercom with Cloudflare and Chatwoot (self hosted), and you have saved $120/mo. Get rid of Ahrefs for Ubersuggest (or no SEO tool at all) to save about $80 more. That leaves you with $81.32/mo. If you try even harder, you can easily bring that under $50.

But I get it. If X tool saves time, why not pay for it? I wouldn't call that frugal though because you are still spending where you can save.

We have been using Tiptap in production for more than a year in Notesnook[0]. Glad to see it finally launching here on HN!

We have had quite a long and rough ride in search of a stable rich text editor. We began with Quill.js then migrated to TinyMCE and then finally settled on Prosemirror. Unfortunately, contenteditable is still absolutely horrible on web browsers, especially mobile ones.

Tiptap is a good choice if you are looking for a framework agnostic and thin abstraction over Prosemirror. However, if you are primarily working with React you should go with Remirror[1]. Tiptap's APIs are heavily inspired by Remirror (almost a duplicate in some places). Remirror takes the edge on the maturity and stability of the API and extensions. The sheer number of utilities offered by them to simplify Prosemirror's APIs is astounding. And trust me, you will need a lot of those utilities eventually. Prosemirror is not an easy API - really, really well designed but not easy.

In the end, though, its Prosemirror that's doing all the heavy lifting. And no matter how many abstractions you put on it, you will have to get really, really close in with Prosemirror's internals. Tiptap or Remirror do not make that any easier or harder aside from the initial bootstrapping.

[0] https://notesnook.com

[1] https://remirror.io

---

Edit: almost forgot this but the only real selling point of Tiptap is their extensive documentation.

I tried it on my end. Built bfs from source using `make release`:

    $ hyperfine -w1 "NODE_ENV=production node ./fdir.mjs" "./bin/bfs /
    home/thecodrr/ -false"

    Benchmark 1: NODE_ENV=production node ./fdir.mjs
      Time (mean ± σ):     965.5 ms ±  53.0 ms    [User: 703.0 ms, System: 1220.5 ms]
      Range (min … max):   858.4 ms … 1041.3 ms    10 runs

    Benchmark 2: ./bin/bfs /home/thecodrr/ -false
      Time (mean ± σ):      1.530 s ±  0.127 s    [User: 0.341 s, System: 2.282 s]
      Range (min … max):    1.401 s …  1.808 s    10 runs

    Summary
      'NODE_ENV=production node ./fdir.mjs' ran
        1.58 ± 0.16 times faster than './bin/bfs /home/thecodrr/ -false'

    $ cat fdir.mjs
    #!/usr/bin/env node

    import { fdir } from "fdir";

    console.log(await new fdir().onlyCounts().crawl("/home/thecodrr").withPromise());
For some reason, reducing the UV_THREADPOOL_SIZE to 2 gives the best result on my machine (I have heard the opposite in case of macOS):
    $ hyperfine -w1 "UV_THREADPOOL_SIZE=2 NODE_ENV=production node ./fdir.mjs" "NODE_ENV=production node ./fdir.mjs" "./bin/bfs /home/thecodrr/ -false"
    Benchmark 1: UV_THREADPOOL_SIZE=2 NODE_ENV=production node ./fdir.mjs
      Time (mean ± σ):     355.8 ms ±  16.1 ms    [User: 479.4 ms, System: 356.0 ms]
      Range (min … max):   328.3 ms … 387.5 ms    10 runs

    Benchmark 2: NODE_ENV=production node ./fdir.mjs
      Time (mean ± σ):     935.4 ms ±  52.7 ms    [User: 695.8 ms, System: 1176.5 ms]
      Range (min … max):   850.6 ms … 1031.9 ms    10 runs

    Benchmark 3: ./bin/bfs /home/thecodrr/ -false
      Time (mean ± σ):      1.534 s ±  0.104 s    [User: 0.353 s, System: 2.307 s]
      Range (min … max):    1.428 s …  1.773 s    10 runs

    Summary
      'UV_THREADPOOL_SIZE=2 NODE_ENV=production node ./fdir.mjs' ran
        2.63 ± 0.19 times faster than 'NODE_ENV=production node ./fdir.mjs'
        4.31 ± 0.35 times faster than './bin/bfs /home/thecodrr/ -false'
Another factor to take into account is that I ran all this on a WSL instance which may or may not affect the performance. However, since both programs are running on WSL, the results should be accurate.

You are using fdir synchronously. Try this:

console.log(await new fdir().onlyCounts().crawl("/home/tavianator/code/android").withPromise());

Would love to see how bfs compares to fdir[0] for directory traversal. Even though fdir is using Node.js underneath, the comparisons I have done with fd & find are pretty close. Of course, bfs would probably be quite a bit faster...but how much faster exactly?

Disclaimer: I am the developer of fdir.

[0] https://github.com/thecodrr/fdir