Back
product

Changelog for 2024

Explore the latest updates and enhancements in our 2024 changelog. New features, performance work, and refinements across the Keldr stack.

Ben Sutherland 10 Feb 2024 5 min read

We shipped a lot in 2024. This post collects the headlines: the features that landed, the rough edges we sanded down, and the work we are most excited about heading into 2025.

What’s new

Voice capture got faster and quieter. Most of our work this year went into the ingestion path — getting from a button press to a confidently-typed transcript in under a second, on devices that other tools wheeze on.

  • Streaming dictation with sub-300 ms first-token latency on Apple Silicon.
  • Offline transcription for sensitive workflows. No data leaves the device.
  • Workspace routing that picks the right destination based on the active app.

Speak naturally. Keldr captures your intent, refines it into finished work, and routes the result across every tool you use.

A quick code sample

Below is a sketch of how the new BlogWithSlug route is wired up. Keldr does not actually use this on the dashboard side, but it is a good example of the patterns we now follow on the website:

"use client";

import { useRouter } from "next/navigation";
import { BlogWithSlug } from "@/lib/blog";

export default function BlogLayout({
  blog,
  children,
}: {
  blog: BlogWithSlug;
  children: React.ReactNode;
}) {
  const router = useRouter();
  return (
    <div className="mt-16 lg:mt-32">
      <div className="xl:relative">
        <div className="mx-auto max-w-2xl">
          <article>
            <header className="flex flex-col">
              <h1>{blog.title}</h1>
              <time
                dateTime={blog.date}
                className="order-first flex items-center text-base text-zinc-400"
              >
                <span className="h-4 w-0.5 rounded-full bg-zinc-200" />
                <span className="ml-3">{blog.date.toDateString()}</span>
              </header>
            <div className="mt-8 prose prose-zinc dark:prose-invert" data-mdx-content>
              {children}
            </div>
          </article>
        </div>
      </div>
    </div>
  );
}

And the corresponding Svelte version, which is closer to what powers this page:

<script lang="ts">
  import type { BlogPost } from "$lib/blog/posts"
  let { post, children }: { post: BlogPost; children: any } = $props()
</script>

<article class="prose prose-zinc">
  <h1>{post.title}</h1>
  <time datetime={post.isoDate}>{post.formattedDate}</time>
  {@render children?.()}
</article>

Tables look fine too

AreaBeforeAfter
First-token (ms)720280
Cold-start (ms)1900540
CPU at idle (%)4.10.9

A custom callout from markdown

You can drop Svelte/HTML straight into markdown and it picks up Tailwind:

Heads up. Custom callout rendered from markdown.

What’s next

We are heading into 2025 with three big bets: deeper integrations, smarter routing, and a much richer dashboard experience. Subscribe to updates from the footer if you want to follow along.