Hacker News new | ask | show | jobs
by skissane 626 days ago
I use Notion because I have to, not because I like it.

Other teams still use Confluence. People said Notion is a lot better than Confluence. Well, I agree I'd rather use it over Confluence, but that's a very low bar for comparison.

For ages they didn't have a find-and-replace feature. I just checked, it looks like they've finally added it in the last few months, but this is the first I notice.

They claim you can export stuff as markdown, but if I export as markdown, edit and reimport, I lose half of the formatting – even basic formatting which is part of the markdown spec.

Their native format (which their API exposes) is a bunch of extremely complex JSON blobs. I thought about writing a tool to let me download stuff, edit it in a sane text editor, then reupload it, but when I saw the complexity I just gave up.

3 comments

(I work at Notion)

Our public API format is not the "native" format used by the Notion editor. The overly-nested format we designed the public API is aimed at supporting statically typed programming languages like Java or Golang that do not have (tagged) union types natively. Instead we represent each option in the union type as a nullable field pointing to a nested object. This makes the structure much easier to decode in these kinds of languages, but does make it more verbose.

For a hypothetical typescript union type:

    | { type: 'plain', text: string, format: Formatting }
    | { type: 'link', text: string, href: string, format: Formatting }
    | { type: 'page-mention', page: { id: UUID, spaceId: UUID }, format: Formatting }
we end up producing a Java-style object like this:

    {
      plain?: {
        text: string,
        format: Formatting
      }
      link?: {
        text: string,
        href: string,
        format: Formatting
      }
      pageMention?: {
        page: {
            id: UUID,
            spaceId: UUID
        },
        format: Formatting
      }
    }
You can see the native format by looking at API traffic in your browser devtools. Generally the native format is more confusing without type annotations.
Switching an enum on a `type` field is very much doable and common practice in statically typed languages.

Rust's serde calls that "internally tagged": https://serde.rs/enum-representations.html

I specifically said "statically typed programming languages like Java or Golang" because those are languages without constructs that can easily represent something like a Typescript union-of-objects. There are many statically typed programming languages that do support union types!

Rust structured enums qualify - each enum case can have fields, so it's natural to represent a Typescript union type using a Rust enum; It's not quite the same (needs a newtype wrapper for each different combination of types in the union) but is very serviceable for the API use-case.

C and Zig have a different "union" concept where the caller needs to switch on a "tag" field like `type` in Typescript but with less compiler guidance to ensure you use the right union variant for a certain tag value.

Java and Go are more limited. Java can represent an "internally tagged" union as a superclass with subclasses, and Go can represent as an interface type with a method for getting the variant, but both require the consumer to know all the subtypes, and perform their own "if canCast(supertypeValue, unionCaseSubclass1) { // handle case 1 } else if ..." structure, which substantially hinders discoverability and requires more work.

Actually today's Confluence is much better than Notion in my opinion.

It has a built in Figma style diagram/flow-chart editor which is handy for architecture documents, infinite array of plugins and the interface is simple, clean and focused.

Notion has become this kitchen sink app where even editing a table is a convoluted mess of an experience.

Try sending the bob straight to an LLM and have it give you markdown. Bet it works.