motyl.dev
TrendingNewsletterBlogNewsAbout
Support
Grzegorz Motyl

© 2026 Grzegorz Motyl. Raising the bar of professional software development.

GitHubTwitterEmail
Home
News
Blog
Me
    /
    motyl.dev
    TrendingNewsletterBlogNewsAbout
    Support
    1. Home
    2. News
    3. Temporal: A 9-Year Journey to Modern JavaScript Time Handling, Vite 8's Rolldown Revolution, and AI Generation Hooks

    Temporal: A 9-Year Journey to Modern JavaScript Time Handling, Vite 8's Rolldown Revolution, and AI Generation Hooks

    Published on 14.03.2026

    #uidev
    #javascript
    #typescript
    bash — 80×24$pnpm dev▶ ready on localhost:3000$git commit -m "feat: og images"$npx tsc --noEmit✓ 0 errorsCODING

    TLDR

    Temporal hits Stage 4 standardization — JavaScript finally has immutable, timezone-aware date/time handling with nanosecond precision after 9 years of TC39 consensus-building. Already shipping in Firefox 139, Chrome 144, and TypeScript 6.0 beta.

    Vite 8 ships Rolldown bundler — A unified Rust-based bundler replaces the dual esbuild+Rollup approach, delivering 10-30x faster builds while maintaining full plugin compatibility. Real-world projects report 38-64% build time reductions.

    TanStack launches generation hooks — React hooks for image generation, text-to-speech, transcription, summarization, and video, with type-safe streaming and server function integration. Same API across all generation types.


    Temporal: The 9-Year Journey to Fix Time in JavaScript

    The problem was baked in from day one. In 1995, Brendan Eich had 10 days to create JavaScript. He pragmatically ported Java's Date implementation directly—a decision made under time pressure that echoed through 30 years of developer pain. Date is mutable (mutations happen in place), doesn't handle month arithmetic correctly (adding one month can silently roll into the next month), and parses "almost ISO" strings ambiguously depending on the browser.

    By the 2010s, this became a critical pain point. JavaScript was powering banking terminals, trading systems, collaboration tools—all in different timezones on earth. Libraries like Moment.js (first released 2011) filled the gap, but at a cost: adding 100+ MB downloads of locale and timezone data wholesale, because most devs didn't know which timezones they'd need.

    Temporal types:

    • Temporal.ZonedDateTime — exact moment + explicit timezone + explicit calendar + daylight saving correctness, fully immutable
    • Temporal.Instant — exact moment in time, nanosecond precision (not milliseconds like Date)
    • Temporal.PlainDate, PlainTime, PlainDateTime — "wall time" without timezone/calendar concerns
    • Temporal.Duration — for arithmetic operations
    • Calendar support — you can do "add one Hebrew month" as a first-class operation, not just format differently

    The implementation was itself a technical milestone. Temporal is the biggest addition to ECMAScript since ES2015, with ~4,500 tests in Test262. Instead of duplicating implementation effort across engines, Google and Boa collaborated on temporal_rs, a Rust library that V8, Boa, and other engines now share. This reduced friction, made the codebase easier to review, and created a maintainable home for fixes post-standardization.

    Temporal: The 9-Year Journey to Fix Time in JavaScript


    Vite 8: Rolldown Powers 10-30x Build Speedups

    Real-world results:

    • Linear: 46s → 6s
    • Ramp: 57% reduction
    • Mercedes-Benz.io: 38% faster
    • Beehiiv: 64% faster

    The migration path was deliberate. A separate rolldown-vite preview package shipped first, letting teams test on real codebases before it became the default in Vite 8 beta. This feedback surfaced edge cases the team fixed before the stable release. CI validated key plugins and frameworks against the new bundler to catch regressions early.

    Additional features in Vite 8:

    • Integrated Devtools — debugging and analysis directly from the dev server
    • Built-in tsconfig.paths support — TypeScript path alias resolution with resolve.tsconfigPaths: true
    • emitDecoratorMetadata support — automatic TypeScript decorator support, no external plugin needed
    • Wasm SSR support — .wasm?init imports now work in SSR
    • Browser console forwarding — browser console logs appear in your CLI (great for agents)
    • @vitejs/plugin-react v6 — now uses Oxc instead of Babel, smaller install size

    The trade-off: Vite 8 is ~15 MB larger than Vite 7 (Rolldown itself is ~5 MB, lightningcss now included is ~10 MB). This was a deliberate choice: better CSS minification and Rolldown's performance optimizations favor speed over binary size.

    What's coming next:

    • Full Bundle Mode — bundle during dev like production, 3x faster startup, 40% faster reloads on large projects
    • Raw AST transfer — JS plugins can access the Rust AST with minimal overhead
    • Native MagicString transforms — string manipulation runs in Rust, logic lives in JS
    • Environment API stabilization — collaborative effort with the ecosystem

    Vite 8.0 is out!


    TypeScript Type Safety: Absorbing Unknown Into the Type Realm

    Foreign JSON (APIs, databases): Parse it with validation schemas like Zod. Don't cast. The absolute worst lie is const user = (await res.json()) as User; because you're asserting the shape of data from across a network boundary. Use Zod's .parse() to get runtime proof. If the API changes shape, you get a clear error instead of "undefined is not a function" three frames down the stack.

    Generic boundaries: One as cast in the utility, validation at the call site. Example: safeFetchJson<T> accepts the cast internally (boundary between any and the typed world), but callers must validate with Zod. This keeps application code cast-free.

    Type guards: When you've already checked a condition but TypeScript can't narrow, write a type guard instead of casting. Example: function isImageNode(node: { type: string }): node is ImageNode { return node.type === 'image'; }. Reusable, and keeps the lie out of application logic.

    Assertion functions: Like guards but throw on failure and narrow for the rest of the scope. Best for preconditions inside functions. For external data, still prefer Zod.

    Catch clauses: catch (err) gives you unknown. Don't cast to Error immediately. Use Error.isError(err) ? err.message : String(err) instead. Works across realms (iframes, workers, vm contexts).

    ORM JSON columns: Type at the schema level using $type<T>() in Drizzle or similar patterns in Prisma. Zero casts at call sites.

    The hierarchy:

    1. Can you validate it? Use Zod (best for APIs, databases, localStorage, URL params)
    2. Can you narrow it? Type guards or assertion functions (discriminated unions, string literals, set membership)
    3. Generic boundary? One as in the utility, validation at call site
    4. Structural plumbing (Proxies, generated code)? Inline disable comment, move on

    Key takeaway: The goal isn't zero as—it's zero unexamined as. Every cast should be a conscious decision, not a reflex.

    Absorbing unknown Into the Type Realm


    Generation Hooks: Type-Safe AI Beyond Chat | TanStack

    Three transport modes:

    1. Streaming (SSE) — Classic server-sent events. Flexible, works with any server framework.
    2. Direct (fetcher) — Just call a function, get JSON back. Synchronous from the user's perspective, fully type-safe.
    3. Server Function Streaming (NEW) — The real innovation. Combines type safety of server functions with real-time streaming feedback. Your fetcher returns a Response (SSE stream), the client auto-detects it and parses in real-time. Input stays fully typed throughout.

    The genius is in the detection: if your fetcher returns a Response, it's treated as SSE. If it returns anything else, it's a direct result. No flags, no configuration, no separate hook.

    Result transforms: Every hook accepts an onResult callback to transform results before storing. TypeScript infers the output type. Example: convert base64 audio to a blob URL for playback.

    Video generation is special. Providers like OpenAI's Sora use a jobs-based architecture (submit prompt → get job ID → poll for status). useGenerateVideo() handles this transparently, exposing jobId and videoStatus as reactive state. Users see "pending", "processing", progress percentages, and finally the video URL—no polling loop required.

    Adapter ecosystem: Generation functions are provider-agnostic by design. Swapping from OpenAI to Anthropic or a local model is a one-line change.

    Key takeaway: 3 lines of hook setup gives you type-safe input, streaming progress, error handling, and abort support. That's the whole feature.

    Generation Hooks: Type-Safe AI Beyond Chat | TanStack Blog


    React Native CI/CD with Expo Workflows

    Speed tiers based on what changed:

    • Full Build (10-20 min) — Native code changed? Full compile, sign, submit on M4 Pro
    • Repack (~2 min) — JS-only changes? Reuse last build, rebundle JS, re-sign. Skip compilation entirely.
    • OTA Updates (<5 min) — Hotfix? Push over-the-air update, no rebuild

    Most teams start by offloading mobile builds to Workflows, then expand. You don't rip out your CI—integrate gradually. Instant jobs (~300ms) for Slack notifications, artifact lookups, lightweight tasks. Zero CI minutes consumed.

    Operators report ~80% reduction in DevOps overhead, freeing engineers to focus on features.

    Key takeaway: From indie devs to enterprises (HipCamp, PrizePicks, InfiniteRed), Workflows replaces sluggish, brittle build processes with something quick and dependable.

    Mobile CI/CD built for React Native


    Just Use Postgres: The Forbidden Monolith

    What this unlocks:

    • Replication magic: Streaming replication gives you every git push, deployed function, and application state through the same WAL stream. One pg_basebackup covers all three concerns (git mirror, artifact store, database replication).
    • Point-in-time recovery: Restore from backup, replay WAL to any moment. You get repository contents, deployed code, and application data all consistent at that exact point in time.
    • Single pg_dump: Backs up application code, git history, and application state all at once.
    • Unified monitoring: Git objects and refs participate in Postgres's MVCC, vacuum, monitoring, connection pooling—all the ops tooling already exists.

    The trade-off: The monolith only works if you accept that a bad deploy can take down your database. That's a management problem, not a technical one, but it needs more than a trigger and EXECUTE to handle safely.

    Disclaimer: This is experimental and proof-of-concept. Large repos will be slow (packfile generator skips delta compression), deploy trigger isn't battle-tested with real applications, no auth, protocol v1 only, no concurrent push handling. It works for the happy path on small repos.

    The insight: when everything is in one database, operational concerns like replication, backup, recovery, and monitoring become dramatically simpler because you're not coordinating across multiple storage systems with different consistency models.

    Just Use Postgres


    Disclaimer

    This article summarizes technical newsletters and curated links for developers. All views and opinions expressed here are for educational purposes. Verify claims and evaluate tools based on your specific needs before adopting them in production.

    ☕ Knowledge costs tokens,fuel meHelp me keep the content flowing
    External Links (6)

    Temporal: The 9-Year Journey to Fix Time in JavaScript

    bloomberg.github.io

    Vite 8.0 is out!

    vite.dev

    Absorbing unknown Into the Type Realm

    solberg.is

    Generation Hooks: Type-Safe AI Beyond Chat | TanStack Blog

    tanstack.com

    Mobile CI/CD built for React Native

    expo.dev

    Just Use Postgres

    nesbitt.io

    Sign in to bookmark these links
    Previous
    Tailwind Weekly #208: Inclusive Dark Mode, CSS Spinning Diagrams, and 5k+ Component Library
    Next
    Ambient Computing via Voice AI Agents: The Golden Age Begins in 2027
    Grzegorz Motyl

    © 2026 Grzegorz Motyl. Raising the bar of professional software development.

    GitHubTwitterEmail