3813 stories
·
3 followers

Programming With Less Than Nothing

1 Share
Read the whole story
emrox
8 hours ago
reply
Hamburg, Germany
Share this story
Delete

Quantity queries using has() selector

1 Share

Here’s a handy little tool for generating CSS with :has() selectors in order to do quantity queries.

adactio.com/links/22206

Read the whole story
emrox
8 hours ago
reply
Hamburg, Germany
Share this story
Delete

Just use cURL

1 Share

What the fuck happened to making HTTP requests? You used to just type curl <a href="http://example.com" rel="nofollow">example.com</a> and boom, you got your goddamn response. Now everyone's downloading 500MB Electron monstrosities that take 3 minutes to boot up just to send a fucking GET request.

It's already on your machine, dipshit

You know what's better than downloading Postman? Not downloading Postman. cURL is already installed on your machine. It's been there since forever. It works. It's fast. It doesn't need to render a fucking Chromium instance to make a web request. It doesn't depend on a service to run. It doesn't require an "Enterprise" subscription for basic features.

It actually does everything

Oh, you need to:

  • Send POST requests? curl -X POST
  • Add headers? curl -H "Header: value"
  • Upload files? curl -F <a href="mailto:file=@file.txt">file=@file.txt</a>
  • Handle cookies? curl -c cookies.txt -b cookies.txt
  • Follow redirects? curl -L
  • Basic auth? curl -u user:pass
  • OAuth? Yeah, it does that too.
  • HTTP/2? HTTP/3? FTP? SFTP? SMTP? IMAP? POP3? LDAP? WebSocket? Fucking Gopher? Yes to all of it.

Meanwhile Postman is over here asking you to create an account to sync your "collections" to the cloud. It's a fucking HTTP request, not your photo library.

The UI/UX is perfect

You know what has great UX? The command line you're already using. No clicking through 47 tabs. No "Workspaces." No "Environments" dropdown menu. Just type the fucking command. Your history is in your shell. Your "collections" are called shell scripts. Your "environments" are called environment variables, and they've existed since 1979.

Want to save a request? Put it in a file. Want to share it with your team? It's text. Copy it. Paste it. Done. No JSON export/import bullshit. No proprietary formats.

It's faster than your bloated piece of shit

cURL executes in milliseconds. You know how long it takes Postman to start? Long enough to question your career choices. And don't even get me started on these new "modern" alternatives like Insomnia and HTTPie Desktop. Congratulations, you've turned a 2MB command-line tool into a 300MB desktop app. Progress!

But muh GraphQL, muh pretty interface!

Shut up. You can pipe cURL to jq:

curl -X POST <a href="https://api.example.com/graphql" rel="nofollow">https://api.example.com/graphql</a> \
  -H "Content-Type: application/json" \
  -d '{"query": "{ users { name } }"}' \
  | jq '.'

Now you have syntax highlighting and JSON parsing. Total install size: ~10MB. Total startup time: instant. Total RAM usage: negligible. Total feelings of superiority: immeasurable.

Don't trust yourself with JSON syntax? Fine, use jo:

curl -X POST <a href="https://api.example.com/api/users" rel="nofollow">https://api.example.com/api/users</a> \
  -H "Content-Type: application/json" \
  -d "$(jo 'user[name]=John' 'user[email]=john@example.com')"

Beautiful. Fast. No Electron or React in sight.

Frequently Asked Dumb Questions

Q: But I can't see my request history!

A: Yes you can, it's called history | grep curl. Or write your commands in a fucking file like an adult.

Q: How do I organize my requests?

A: Put your shell scripts into directories, genius.

Q: The syntax is hard to remember!

A: Type man curl or curl --help. Or literally just Google it once and save the command. You can remember 400 Kubernetes commands but not curl -X POST?

Q: What about team collaboration?

A: It's a text file. Put it in Git. You know, that thing you should be using anyway? Now your requests have version control, code review, and diffs. For free. Revolutionary, I know.

Q: But Postman has testing and automation!

A: So does cURL in a shell script with || and && and actual programming languages. You want assertions? Pipe to grep or write a 3-line Python script. Done.

Q: What about cookie management?

A: -c to save cookies, -b to send them. This has been solved since 1999. Read the manual.

Just use cURL

It's been downloaded over 20 billion times. It supports 25+ protocols. It's in cars, refrigerators, TV sets, routers, printers, phones, and every goddamn server on the planet. It's maintained by people who actually understand networking, not some VC-funded startup that'll slap "AI" on it next quarter.

Stop using resource-hogging garbage. Stop creating accounts for basic functionality. Stop pretending you need a GUI to make HTTP requests.

Just use cURL.

Read the whole story
emrox
2 days ago
reply
Hamburg, Germany
Share this story
Delete

State and rerenders

1 Share

State-based vs Signal-based rendering

When we think about state management in front-end frameworks, we often focus on the API—hooks, observables, or signals. However, there's a deeper paradigm shift at play: where rendering happens. Traditional state management like React hooks triggers renders at the point where state is created, while signal-based approaches like Preact Signals or Solid.js trigger renders only where state is consumed.

This shift from "render where you create state" to "render where you use state" has profound implications for performance, code organization, and mental models.

The Core Difference

In traditional state management with React hooks, when you call useState, any update to that state causes the component—and all its descendants—to re-render. It doesn't matter whether those descendants actually use the state; they're caught in the render wave simply because they're children of the component that holds the state.

const Parent = () => {
  const [count, setCount] = useState(0);
  return (
    <>
      {/* re-renders even though it doesn't use count */}
      <ChildA />
      <ChildB />
      {/* re-renders, actually uses count */}
      <ChildC count={count} />
    </>
  );
};

With signal-based rendering, the paradigm inverts. A signal is a reactive primitive that tracks its own dependencies. When you create a signal, it doesn't trigger re-renders at the creation site. Instead, rendering only occurs at components that actually access the signal's value.

const Parent = () => {
  const count = useSignal(0);
  return (
    <>
      {/* do NOT re-render */}
      <ChildA />
      <ChildB />
      {/* only re-renders if it reads count.value */}
      <ChildC count={count} />
    </>
  );
};

This granular reactivity means only the precise components that depend on the signal will re-render when it updates. The mental model shifts from "prevent unnecessary re-renders" to "re-renders only happen where they're needed."

Context: The Paradigm Shift Amplified

This difference becomes even more pronounced when dealing with the Context API. In React, when you distribute state through context and update it, all consumers of that context re-render, regardless of whether they actually read the updated value.

const CountContext = createContext();

const Provider = ({ children }) => {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('');
  return (
    <CountContext.Provider
      value={{ count, name, setCount, setName }}
    >
      {children}
    </CountContext.Provider>
  );
};

const ComponentA = () => {
  const { name } = useContext(CountContext);
  // Re-renders when count changes,
  // even though it only uses name.
  return <div>{name}</div>;
};

With signals in context, the reactivity is surgical. The context can hold signals, and only components that actually call .value on a signal will subscribe to its updates.

const CountContext = createContext();

const Provider = ({ children }) => {
  const count = useSignal(0);
  const name = useSignal('');
  return (
    <CountContext.Provider value={{ count, name }}>
      {children}
    </CountContext.Provider>
  );
};

const ComponentA = () => {
  const { name } = useContext(CountContext);
  // Only re-renders when name changes,
  // not when count changes
  return <div>{name.value}</div>;
};

This is a game-changer for large applications where context is used to distribute state across many components. You no longer need to split contexts to prevent unnecessary re-renders or reach for complex optimization patterns.

Rendering Propagation

Let's visualize how re-renders propagate through a component tree:

State-Based (React Hooks)

In state-based rendering, when state updates, the entire subtree from the point of state creation re-renders. You need to manually optimize with React.memo, shouldComponentUpdate, useMemo, and useCallback to prevent unnecessary work.

All descendants re-render (shown in red), regardless of whether they actually use the state. Only GC 2 genuinely needs the update, but Child 1, Child 2, Child 3, GC 1, and GC 3 all re-render unnecessarily.

Signal-Based (Preact Signals / Solid.js)

In signal-based rendering, only components that actually read the signal's value re-render. The component hierarchy is irrelevant—what matters is data dependency, not component ancestry.

Only GC 2, which actually accesses signal.value, re-renders (shown in green). All other components remain unchanged (shown in gray), even though they're part of the same component tree.

Granular Control with Control Flow

Preact has a few utilities to take this further with control flow components like Show and For. These components scope reactivity even more precisely.

const items = signal([]);
// When the items signal updates, only the affected items re-render
<For each={items}>
  {(item) => (
    <div>
      {/* Only this item re-renders when item.value changes */}
      <span>{item.name.value}</span>
      <button
        onClick={() => item.count.value++}
      >
        {item.count.value}
      </button>
    </div>
  )}
</For>

Compare this to classic hooks, where changing an item in a list might trigger re-renders across sibling items, the parent component, and any other children—unless you've carefully memoized everything.

These control-flow components scope the re-render of a Signal (be that a derived computed or plain signal value) down to its JSX children.

Performance Implications

This paradigm shift has tangible performance implications:

  • Less computational work: Fewer components re-render means less JavaScript execution. You're not running render functions, diffing virtual DOM, or applying effects for components that don't care about the state change.
  • Reduced bundle size: No need for memoization helpers like React.memo, shouldComponentUpdate, useMemo, or useCallback. The framework's reactivity system handles optimization automatically.
  • Predictable performance: Re-render locations are determined by where signals are accessed, not by component hierarchy. This makes performance predictable and debugging easier—you can trace which components update by following signal reads.
  • No prop drilling: Signals can be passed through context or even imported directly without triggering unnecessary re-renders. You're not forced to split contexts or create provider pyramids.

When State-Based Makes Sense

It's worth noting that state-based rendering isn't inherently bad. For small components or applications where re-renders are cheap, the hooks model is simple and sufficient. The cost of re-rendering a few dozen components is often negligible.

The trade-off becomes significant in:

  • Large component trees with deep nesting
  • High-frequency updates (animations, real-time data)
  • Applications with complex state distribution (multiple contexts, global state)

Conclusion

The shift from state-based to signal-based rendering is more than a performance optimization—it's a paradigm shift in how we think about reactivity. Instead of preventing re-renders through memoization, we only trigger re-renders where they're needed.

This inversion—from "render where you create state" to "render where you use state"—aligns our code with the actual data flow. It makes applications faster by default and simplifies the mental model: if you read a signal, you'll update when it changes. If you don't, you won't.

As frameworks like Preact Signals and Solid.js demonstrate, this isn't a theoretical improvement—it's a practical one that makes building performant, maintainable applications easier. The future of front-end reactivity is fine-grained, and it's already here.

Read the whole story
emrox
3 days ago
reply
Hamburg, Germany
Share this story
Delete

Physics Insight

2 Comments and 6 Shares
When Galileo dropped two weights from the Leaning Tower of Pisa, they put him in the history books. But when I do it, I get 'detained by security' for 'injuring several tourists.'
Read the whole story
emrox
9 days ago
reply
Hamburg, Germany
Share this story
Delete
2 public comments
llucax
10 days ago
reply
It happened to me too.
Berlin
alt_text_bot
10 days ago
reply
When Galileo dropped two weights from the Leaning Tower of Pisa, they put him in the history books. But when I do it, I get 'detained by security' for 'injuring several tourists.'

HTML’s Best Kept Secret: The output Tag

1 Share

Comments

Read the whole story
emrox
10 days ago
reply
Hamburg, Germany
Share this story
Delete
Next Page of Stories