Skip to content

Instantly share code, notes, and snippets.

import {
useCallback,
useEffect,
useMemo,
useRef,
useState,
type DependencyList,
} from "react";
import {
DynamicInterval,

DynamicInterval

Lightweight scheduler for running arbitrary work on a dynamic interval. Ideal for backoff retry loops, background autosaves, and heartbeat polling. Ensures runs never overlap and supports adaptive delays, jitter, and full lifecycle controls.

Features

  • Non-overlapping runs (no reentrancy) with automatic rescheduling after each run
  • Dynamic delay calculation via strategies (exponential, linear, constant, or custom)
  • Jitter support to avoid thundering herds (none, full, or bounded ±percentage)
  • Lifecycle controls: start, pause, resume, stop, runNow, resetBackoff
import { type Remix } from "@remix-run/dom"
import { dom } from "@remix-run/events"
import { STATES } from "./lib/states.ts"
export function App(this: Remix.Handle) {
let fetchState: "idle" | "loading" | "loaded" = "idle"
let cities: string[] = []
return () => (
<form
@ryanflorence
ryanflorence / feedback.md
Last active September 18, 2024 17:20
Feedback for José

Article Feedback

Shared Links UI

I decided to give it a try, find some bugs, and discuss possible root causes.

This UI doesn't use Remix's built-in conventions, it uses React Query talking to a backend API like many React SPAs.

The behavior shown in this video is not the behavior of Remix: https://x.com/josevalim/status/1832509464240374127

You can leave them in the module scope and use the new types:

import {
-  LoaderFunctionArgs,
-  ActionFunctionArgs,
+  LoaderArgs,
+  ActionArgs
  useLoaderData,
+  defineRoute

View Transitions

Scroll Restoration

When the user has a history stack with element transitions, it's possible for them to scroll the element out of view on one or both pages. This can cause elements to translate thousands of pixels across the document and should be avoided.

Here are a few product-level use cases that I would consider good practice with a the proverbial grid-to-hero-image CSS transform.

Scroll Position Priority

function App() {
return (
<Routes>
<Route path="/" element={<Root />}>
<Route index element={<Index />} />
<Route path="projects" element={<Projects />} />
</Route>
</Routes>
);
}
import type { V2_HtmlMetaDescriptor, V2_MetaFunction } from "@remix-run/node";
export const mergeMeta = (
overrideFn: V2_MetaFunction,
appendFn?: V2_MetaFunction,
): V2_MetaFunction => {
return arg => {
// get meta from parent routes
let mergedMeta = arg.matches.reduce((acc, match) => {
return acc.concat(match.meta || []);
import { riff, route, html, indexRoute } from "../riff/riff.mjs";
import { serve } from "../riff/riff-express.mjs";
import {
deleteTask,
getProjects,
getTasks,
getUser,
sendEmail,
updateTask,
createTask,
import { useFetcher } from "@remix-run/react";
import { useCallback, useMemo } from "react";
export function useRevalidator() {
let fetcher = useFetcher();
let revalidate = useCallback(
() => {
fetcher.submit(null, { action: "/", method: "post" });
},