Skip to content
Frontend Feeds
  • Today
  • Archive
  • Sources
  • Categories
    • The Giants6 Sources
    • Multi Author Blogs18 Sources
    • Top Front-end Bloggers25 Sources
    • More Front-end Bloggers77 Sources
    • Browsers, engines, etc.11 Sources
    • Libraries, Frameworks, etc.12 Sources
    • Company/Startup Blogs12 Sources
    • Developer/Designer News4 Sources
    • YouTube Channels13 Sources
    • Podcasts7 Sources

Today

Front-end, in one read.

The latest from the sources worth following, newest first.

Saturday, 14 November 2026

  • DEV CommunityThe Giantsread at source

    Service area map with ZIP code checker in React

    The client request I hear most often on home services sites is some version of "can the map show all the areas we serve?" The first few times I answered it with an embedded Google Map and a list of suburbs. It looked like every other contractor site and it did not answer the visitor's real question, which is not "where are you" but "will you come to me." The Service area block in Facade is the version I settled on after building this section for HVAC companies, plumbers and cleaning services. Here is how it is put together. Zones as data, not as pixels The first decision is to treat service zones as data. Each zone is an object with an id, a display name, a shape, a label anchor, the cities inside it and the ZIP codes it covers. The map, the zone list and the ZIP checker all read from the same array, so adding a zone means adding one object, not editing three places. import type { ServiceZone } from "@/components/facade/service-area" ; const zones : ServiceZone [ ] = [ { id : "north" , name : "North Austin" , path : "M150 40 L238 30 L262 70 L232 108 L170 120 L136 84 Z" , labelX : 198 , labelY : 76 , cities : [ "Allandale" , "Crestview" , "Domain" , "North Burnet" ] , zips : [ "78757" , "78758" , "78759" , "78727" ] , eta : "Same day" , } , { id : "central" , name : "Central Austin" , path : "M156 172 L190 214 L248 200 L270 252 L214 296 L140 284 L118 228 Z" , labelX : 190 , labelY : 250 , cities : [ "Zilker" , "Travis Heights" , "Bouldin Creek" , "Circle C" ] , zips : [ "78704" , "78745" , "78748" , "78749" ] , eta : "Same day" , } , ] ; The eta field is optional and it is the field that does the selling. "Same day" next to a zone name tells a visitor with a broken furnace more than any paragraph. For zones further out, "Next day" is honest and still useful. A stylized SVG map instead of Google Maps The shapes are SVG paths in a fixed 400 by 320 viewBox. That sounds like a step backward from a real map, so let me explain why I prefer it on a marketing page. A Google Maps embed loads a third party script, a tile set and its own fonts. On a mobile connection that is a noticeable hit to Largest Contentful Paint, and Google's own Core Web Vitals guidance treats 2.5 seconds as the threshold for a good LCP. An inline SVG with six polygons costs nothing. It also inherits your theme: the zones use currentColor and the brand token, so the map looks like your site in light and dark mode instead of a gray rectangle with a red pin. The other reason is honesty. Real service areas are not perfect circles around a shop. They follow highways, rivers and county lines, and a hand drawn polygon communicates "we know this town" better than a radius overlay. The decorative river line in the Facade block has a legend label you can rename or hide with riverLabel="" . Drawing the paths is a one time task. I open the real service area in a map tool, sketch the polygons on a 400 by 320 grid and copy the coordinates. Half an hour per client, and the result is a map that never changes under you when a map provider updates its styles. Keyboard and screen reader behavior Each zone is focusable. Arrow keys move between zones, Enter or Space selects one, and the zone list on the side expands to show its cities and ZIP codes. The SVG itself is a role="group" with a label, so a screen reader user hears "Service area map" and can tab into the list instead of being handed a pile of path elements. The ZIP code checker The checker is a small form under the map. The input accepts digits only and stops at five; the onChange handler strips everything else, so pasting "78704-1234" leaves "78704". On submit, the component validates against ^\d{5}$ and then runs a lookup: const zone = zones . find ( ( z ) => z . zips . includes ( zip ) ) ?? null ; That is the whole algorithm. No geocoding, no API key, no rate limits. The trade off is that you have to maintain the ZIP list, which for a local business is a list of twenty to sixty codes they already know by heart. The result messages are functions, so you can write them in the client's voice: import { ServiceArea } from "@/components/facade/service-area" ; ServiceArea eyebrow = "Service area" heading = "Heating and cooling across greater Austin" description = "Two hour arrival windows in every zone. Enter your ZIP to confirm." zones = { zones } hqLabel = "Dispatch on Burnet Rd" hqX = { 200 } hqY = { 160 } checkerLabel = "Do we serve your address?" checkerPlaceholder = "5 digit ZIP" successMessage = { ( zip , zone ) => `Yes. ${zone.name} gets ${zone.eta?.toLowerCase() ?? "fast"} service.` } failureMessage = { ( zip ) => `${zip} is outside our area for now.` } ctaLabel = "Schedule a visit" ctaHref = "/book" waitlistLabel = "Tell us when you expand" waitlistHref = "/waitlist" /> A successful check also selects the matching zone on the map, so the visitor sees their neighborhood light up at the same moment they read the answer. The animated result state Three states need motion here, and each one is small. An invalid entry, say four digits, shakes the input. The block increments a counter on each failed submit and keys the shake animation off it, which means the shake replays on every attempt instead of only the first. A match renders a success card with the zone name, the ETA and a CTA button. A miss renders a card with the failure message and a waitlist link, because a "no" with a next step keeps the lead instead of losing it. Both cards animate in through AnimatePresence with mode="wait" , so switching from a yes to a no does not stack two cards for a frame. All of it respects prefers-reduced-motion . The block reads useReducedMotion() and skips the shake and the entrance transforms for visitors who asked for less movement. Linking zones to city pages The service area is also an internal linking tool. Most home services sites have a page per city or suburb for local search. Add an href to your own data shape, or use the zone id to build the link, and render the city list as links in the panel next to the map. A visitor who finds their zone can jump straight to "AC repair in Round Rock," which is the page you want ranking for that query. I keep the zone array in a single lib/service-area.ts file and import it into the map block, the footer's service list and the city pages' generateStaticParams . One file, three consumers, no drift. Installing it The Service area is a Pro block. It installs from the private registry once your license key is in components.json , which is a one time step covered in the installation docs . npx shadcn@latest add @facadeui/service-area The file lands in components/facade/service-area.tsx and the only dependencies are motion and lucide-react . On an HVAC site I put it fourth, right after the process steps and before the reviews, because by then the visitor knows what the company does and wants to know whether it applies to them. FAQ Can I use real geographic shapes instead of hand drawn polygons? Yes. Export county or ZIP boundaries from a GIS source as SVG paths, scale them into the 400 by 320 viewBox and paste the path strings into the zone objects. The component does not care where the path came from. What about addresses, not ZIP codes? ZIP codes are deliberate. An address lookup needs a geocoding API, which adds a key, a cost and a privacy notice. Five digits are enough to answer "do you come to me" and most people know their ZIP without looking it up. How many zones work before the map gets crowded? Four to eight. Beyond that, labels start overlapping in the fixed viewBox. If a client covers a whole metro region, group suburbs into larger zones and list the individual cities in the panel instead of drawing each one. Originally published at https://facadeui.com/blog/service-area-map-react?utm_source=devto&utm_medium=social&utm_campaign=art-service-area-map-react

  • DEV CommunityThe Giantsread at source

    PostgreSQL 19 Ships on 19 November and PostgreSQL 14 Leaves Support

    TL;DR PostgreSQL is an open-source relational database that teams install on their own servers, and the project supports each major version for five years before a final minor release ends the branch. The PostgreSQL project's RC 1 announcement, published on 15 October, schedules PostgreSQL 19 general availability for 19 November 2026. A second candidate, PostgreSQL 19 RC 2, arrives on 12 November, the same day as the quarterly update release for supported versions. PostgreSQL 14 leaves support on that same 12 November with version 14.24, so a cluster on 14 stops receiving fixes that day. PostgreSQL 19 brings REPACK, a single command that replaces VACUUM FULL and CLUSTER, and REPACK (CONCURRENTLY) rebuilds a table without an access-exclusive lock. The same release adds pg_plan_advice and pg_stash_advice for planner decisions, logical replication of sequence values, a start for logical replication without a restart, and a WAIT command that lets a standby wait on a log position. Defaults change under an upgraded cluster: JIT ships disabled, max_locks_per_transaction moves to 128, standard_conforming_strings is always on, RADIUS authentication is gone, and inet and cidr indexes move to GiST. The path off version 14 runs through pg_upgrade or a dump and restore, and pg_upgrade refuses clusters that carry btree_gist indexes on inet or cidr. The planning point: the version a team runs is a support date, and the date sits on the project's published calendar. This release-notes briefing draws its dates from two PostgreSQL project documents and focuses on clearing PostgreSQL 19's documented incompatibilities before version 14 support ends. The 19 release notes carry an overview that names each headline feature, and the 19 RC 1 announcement sets the schedule plainly: RC 2 on 12 November 2026, general availability on 19 November 2026. Netics visual, 11 November 2026: what a minor release is and what installing one actually involves. The project supports each major version for five years The versioning policy gives a major version five years of bug and security fixes counted from its first release, and the last of those arrives as a final minor release. After that the branch sits unsupported. Minor releases land at least once every three months, targeted at the second Thursday of February, May, August and November. That calendar is the practical part. A team planning a migration can read the final-release column and see the wall before it arrives, which is a rare luxury in infrastructure planning. The project's own support table, read on 11 November 2026: version 14 lists 12 November 2026 in the final-release column, version 18 lists November 2030. Page from https://www.postgresql.org/support/versioning/ . PostgreSQL 14 leaves support on 12 November Version 14 first shipped on 30 September 2021, and the support table lists 14.24 as its current minor release with a final release date of 12 November 2026. After that final minor release, version 14 becomes unsupported. The release notes provide an inventory of incompatibilities. An operational decision also needs an inventory of the extensions and drivers used by the application. Rehearse the chosen migration route on a production-like copy and run the critical queries. Verify backups, the rollback procedure and the maintenance-window duration before approving the migration. The announcement as published on 15 October 2026, naming RC 2 on 12 November and general availability on 19 November. Page from https://www.postgresql.org/about/news/postgresql-19-rc-1-released-3409/ . PostgreSQL 19 arrives on 19 November with REPACK The release notes describe REPACK as the command that replaces VACUUM FULL and CLUSTER. The old commands remain for compatibility. REPACK (CONCURRENTLY) adds the version most operators want: rebuilding a table without taking an access-exclusive lock on it. Planner control arrives as two extensions. pg_plan_advice stabilizes and controls planner decisions, and pg_stash_advice applies stored advice automatically based on a query. Autovacuum also gains parallel index processing and a scoring system that orders which tables it should reach first, on top of I/O worker processes that scale through io_min_workers and io_max_workers. The overview section of the release notes, where the feature list and the migration requirements sit at the top of the page. Page from https://www.postgresql.org/docs/release/19.0/ . Replication gets the two changes that matter most on a busy cluster. Logical replication can be switched on with wal_level set to replica without restarting the server, and sequence values now replicate. A WAIT command lets a standby wait until a log position has been written, flushed or replayed. Defaults change under an upgraded cluster Five defaults shift under the cluster a team restores into 19: JIT is disabled by default, because the optimizer cost that used to trigger it proved unreliable. Sites running large analytical queries need to enable it deliberately. max_locks_per_transaction moves from 64 to 128, and the release notes say the lock size allocation changed so settings must double to hold their previous capacity. standard_conforming_strings is forced on in the server. A dump taken with a pre-19 pg_dump while the setting was off will not load into 19. RADIUS authentication is removed, on the grounds that support existed only over UDP and that transport is unfixably insecure. inet and cidr indexes default to GiST, and pg_upgrade refuses clusters carrying btree_gist opclasses on those types because the old opclasses could exclude rows that belong in the result. Netics visual, 11 November 2026: the setting-level differences between a 14 cluster and a 19 cluster, drawn from the release notes. pg_upgrade decides the path off version 14 The release notes accept three migration routes: a dump and restore with pg_dumpall, pg_upgrade, or logical replication. For planning purposes, treat pg_upgrade as a route that needs an explicit preflight check. Two pg_upgrade refusal conditions are worth checking before a maintenance window: clusters with btree_gist indexes on inet or cidr, and clusters that use carriage returns or line feeds in database, role or tablespace names. Separately, dumps produced by pre-19 tools while standard_conforming_strings was off will not properly load into PostgreSQL 19. Each is a configuration fact that can be found in advance, and each one turns a migration into a debugging session when it surfaces mid-run. There is also a spare SQL. MULE_INTERNAL encoding is gone, so a database that uses it needs a dump and restore into a different encoding. The mark the PostgreSQL project publishes for press use. Image from https://www.postgresql.org/media/img/about/press/elephant.png . Application compatibility deserves priority during upgrade planning, including dependencies introduced through custom web and mobile development . The five-year calendar supplies a deadline; migration safety depends on testing the chosen route and clearing PostgreSQL 19's documented incompatibilities and pg_upgrade refusals before the maintenance window. Originally published on the Netics blog .

  • DEV CommunityThe Giantsread at source

    I Built a Tiny Tool to Fix My Own RMD Confusion

    Every year, around December, I find myself staring at a spreadsheet trying to figure out how much money I need to pull out of my retirement accounts to avoid an IRS penalty. It’s a ritual that feels unnecessarily complex for something that should be straightforward: look up your age, find the divisor, divide your balance. That’s it. But finding the right table for the current year is surprisingly annoying. Search results are cluttered with outdated PDFs, confusing UI from major financial institutions, and ads for investment services I don’t need. I just wanted a clean, fast way to calculate my Required Minimum Distribution (RMD) using the official IRS Uniform Lifetime Table. So, I built a small tool called RMD Table. It’s not a platform. It’s not an app with a login system. It’s a single-page utility that does one thing well: calculates your RMD based on the latest regulation. The Problem with Existing Tools Most financial calculators are bloated. They ask for your entire financial history, your risk tolerance, and your email address before showing you a number. For a simple division problem, this feels like overkill. I wanted something that loads instantly. No JavaScript frameworks if possible, no heavy CSS frameworks, and no tracking scripts. Just HTML, CSS, and a tiny bit of vanilla JS. The goal was to make the tool feel invisible. You come in, you see your number, you leave. When I started building, I looked at a few existing options. Some were great but required an account. Others were simple but used outdated tables from previous years. The IRS updates the Uniform Lifetime Table occasionally, and ensuring the tool always reflects the current regulation is key. I wanted to avoid the common pitfall of hardcoding values that might become stale. How It Works The logic is surprisingly simple. The tool takes two inputs: your age and your December 31 account balance. It then looks up the corresponding divisor from the IRS Uniform Lifetime Table for the current year. For example, if you are 72 years old, the divisor might be 25.6. If your balance is $100,000, your RMD is $100,000 / 25.6 = $3,906.25. The challenge wasn’t the math; it was the UX. I wanted the interface to be responsive and accessible without sacrificing speed. I used CSS Grid for layout because it’s lightweight and handles different screen sizes gracefully. The font stack uses system fonts to avoid loading external resources. This keeps the First Contentful Paint under 1 second on most devices. I also added a small feature that many tools miss: context. Many calculators just spit out a number. But the IRS rules can be tricky. Did you know your first RMD has a different deadline than subsequent ones? Did you know if you miss the deadline, the penalty is 25% of the shortfall? I included brief, clear notes below the result to explain these nuances without overwhelming the user. Why Build Something So Small? In an era of mega-apps and complex SPAs, building a single-purpose tool feels refreshing. It forces you to prioritize clarity. Every element on the screen has to earn its place. There’s no room for decoration. I used a minimal CSS reset and kept the JavaScript under 5KB. No libraries. No build steps. Just a plain HTML file served statically. This makes it incredibly fast to deploy and easy to maintain. If the IRS updates the table next year, I just edit a JSON object in the script. Done. The tool is now live at rmdtable.com . It’s simple, fast, and does exactly what it says on the tin. I’m using it myself every December, and it saves me about five minutes of searching and comparing different websites. What’s Next? Right now, the tool only supports the Uniform Lifetime Table. There are other tables for beneficiaries and married couples with younger spouses, but those are edge cases. I’ll add them if enough people ask. For now, I’m focused on keeping it lean. No analytics beyond basic page views. No pop-ups. Just a clean calculation. If you’ve ever struggled with RMD calculations, I’d love to hear your feedback. What’s the most confusing part of the process for you? Is it finding the right table, understanding the penalties, or something else entirely?

  • DEV CommunityThe Giantsread at source

    Copilot code review never sets a blocking state. I checked 55 merged PRs.

    PR 337469 in microsoft/vscode got two Copilot reviews 52 minutes apart, on the same commit (352dd22d). The first said "Needs a closer look" and described four unresolved moderate issues. The second said three issues remained. Both bodies ended with the same structured line: Findings: None . So on one unchanged diff, the summary text changed, the issue count changed, and the structured findings field reported nothing either time. I went looking for how common that is, and the answer is that the verdict is not part of the review's state at all. A review object has a state, and Copilot's is always COMMENTED GitHub's REST docs for pull request reviews describe a review as comments "grouped together with a state and optional body comment". That state field is what branch protection reads. Copilot code review writes COMMENTED . I sampled merged PRs from microsoft/vscode in two slices of 30 ( state=closed&sort=created&direction=desc ), filtered to merged_at != null , then pulled every review object per PR and filtered to user.login == copilot-pull-request-reviewer[bot] . 28 PRs in the first slice and 27 in the second had a Copilot review. Every review object across all 55 was state COMMENTED . Zero APPROVED , zero CHANGES_REQUESTED . That matters because of what reacts to state. GitHub's protected branch docs describe the merge failure you get when a review sits in a blocking state ( GH006: Protected branch update failed... Changes have been requested ), and the optional setting that dismisses stale approvals when the diff changes after approval. Neither path touches a COMMENTED review. A review that is never blocking cannot block, and it cannot go stale either, because there was never an approval to invalidate. The heading is UI text. GitHub's code review concept docs say Copilot's reviews do not count toward required approvals by default, and that enabling Copilot approvals is a separate repository, organization, and enterprise setting. When that setting is on, a new push dismisses the approval. When it is off, the "Approval recommended" you are reading satisfies nothing. Half the merged PRs carried a "Changes recommended" at merge time Final Copilot review per PR, first slice, 28 merged PRs: 16 Approval recommended 9 Changes recommended 3 Needs a closer look 12 of those 28 merged with a non-approval verdict standing. The older slice (n=27) came out 14 Changes recommended, 12 Approval recommended, 1 Needs a closer look, with 15 merging on a non-approval verdict. Roughly half in both. None of that is a bug report. A reviewer that informs without gating is a defensible design, and teams treating it as advisory are getting what the product promises. The problem shows up when you turn it into a metric. Count "AI approvals" or "AI blocks" from the review state and you get 0 and 0, on every repo, forever. Count it from the heading text and you are counting a string the product edits on its own schedule. The verdict does not follow the findings list 19 of the 28 final reviews in the first slice reported zero open findings. Three of those still ended with "Needs a closer look". So the heading and the findings list are computed separately, and PR 337469 is the visible case: a summary describing unresolved issues sitting next to a findings field reading None. The second review in that pair is worth reading closely for another reason. It flagged a "previously missed issue" in code that had not changed since the first review. Same commit, same files, one new finding. Requesting a fresh assessment does not buy you a stable one. The verdict is usually rendered against a diff that no longer exists 13 of the 28 final reviews in the first slice, and 15 of 27 in the second, sat on a commit that was not the PR head at merge time. The reviewed commit is exposed as commit_id on the review object, and comparing it to head.sha costs one call. That combination is why the "stale verdict" reading misleads when you attribute it to the reviewer. For human approvals, GitHub records the approved diff state and can dismiss the approval when the diff moves. For a COMMENTED review, nothing is recorded and nothing is refreshed, so an off-head verdict is the normal end state. Report it as a coverage caveat next to any defect count, since the reviewer never saw the final version of the change. Re-review is rare, and the second review is a delta In an updated-sorted slice of 28 merged PRs, 24 had exactly one Copilot review. Across the two created-sorted slices, 3 of 55 had more than one. The review bodies invite you to request a fresh assessment, and almost nobody does. That matters more after the November 6 changelog , which says that on later reviews of the same PR, findings unrelated to your recent changes are collapsed and then hidden. A second review reports the delta against your last push. It does not re-read the whole change. Run a reviewer twice, diff the bodies, and a drop in findings reads like an improvement when it is a narrower scope. Two reviews, one diff, different output The same-commit pair is the artifact I would put in front of anyone building a quality score. One diff, one commit, two review requests, two different issue counts, one of them inconsistent with its own findings field. That is the failure mode of a flaky test: the instrument changes its answer while the input stays fixed. A single-run score from that instrument is a sample of one. The cheap version of the test costs nothing. Open a PR, request a review, request it again on the same commit, compare the two bodies line by line. If the counts move, no quality number you compute from one run survives a re-run. What to record instead Five fields, one row per review run: The reviewed commit id ( commit_id ) and the PR head sha at the time you read the result. The findings count from the structured part of the body, matched against every shape the body has used, not one string. The effort level in use, because Lite, Balanced and Max are different products. The verdict heading, stored as text, with the date you read it. Whether a second review happened, and what changed between the two. On effort, the concept docs publish estimated AI credit consumption per review at roughly $0.25 average for Lite, $1.50 for Balanced and $10 for Max, with a warning that consumption rises with PR size and repository custom instructions. The November changelog adds that Balanced now uses three reviewer models with another model combining their findings. A quality number with no effort level attached is not comparable to anything. On the counter itself, the body format keeps moving. The November 6 update moved the effort label into a compact footer, merged skipped and excluded files into one "Files not reviewed" section, and added explicit attribution fields to the REST and GraphQL APIs so you can identify Copilot's reviews and comments directly. Key your metrics on those fields. A grep for a heading string is a metric that breaks on a UI release. If you want a gate, buy a gate Advisory review and required review are separate purchases, and the tooling reflects that. CodeRabbit's configuration reference exposes reviews.auto_approvals.enabled (default false) and states that missing, failed, disabled or stale required assessments withhold approval, which gives you a documented condition set to test against your own PRs. Kodus sits at the other end: self-hosted, AGPLv3, bring your own model, with review rules scoped to an organization, a repository or a path, so the scope and the pass conditions live in your config and you can re-run them. Both are testable in the sense that matters here, which is that you can predict from the docs what happens to the verdict when the diff changes. With Copilot's default configuration the answer is nothing, and the docs say so. Before comparing tools, settle file scope first. I wrote about the documented skip list and what it does to a head-to-head . And if you are still building the baseline for review time, the fixed-slice protocol is the shape I would reuse. The number your branch protection sees Copilot code review produces a comment with a verdict in it. Your branch protection reads a review state, and that state was COMMENTED on all 55 merged PRs I sampled. Count the state, treat the heading as UI text, and record the reviewed commit id next to every result you keep. That is the difference between a metric and a screenshot.

  • DEV CommunityThe Giantsread at source

    Codifying scotthavird.com in Terraform

    Codifying scotthavird.com in Terraform For years this site lived in two places at once: the Docusaurus repo and a scattering of Cloudflare dashboard clicks. Pages project settings, custom domains, zone security toggles, and an email signup API that only existed in AWS — none of it was reviewable in a PR. That drift is fine until it isn't. I hit the www redirect trap on my own domain. Preview builds failed because Node 18 was still configured in the dashboard while Docusaurus 3.9 requires Node 20. Each fix was another manual change with no audit trail. So I codified the whole stack in iac/ and retired the GitHub Actions deploy workflow in favor of native Cloudflare Pages builds. What Moved Into Terraform The iac/ directory now owns four concerns that used to be split across dashboards: Concern Resource Why codify it Site hosting cloudflare_pages_project Build command, Node version, preview branch rules Zone security null_resource + Cloudflare API SSL strict, HSTS preload, TLS 1.3 Email signup API Gateway + Lambda + DynamoDB + SES Homepage newsletter form DNS for email cloudflare_record (SES verification, DKIM) Deliverability without manual TXT records The Docusaurus site itself stays in the same repo. Cloudflare Pages builds main on every push — no separate deploy workflow. Cloudflare Pages: The Important Details The Pages project resource looks straightforward, but a few fields matter in practice: build_config { build_command = "yarn build" destination_dir = "build" } deployment_configs { production { environment_variables = { NODE_VERSION = "20" SUBSCRIBE_API_URL = aws_apigatewayv2_api . main . api_endpoint } } } Node 20 — Docusaurus 3.9.2 requires it. The dashboard was still on 18, which meant every PR preview failed with yarn: command not found or engine warnings. Setting it in Terraform means preview and production stay aligned. SUBSCRIBE_API_URL — Docusaurus reads this at build time via process.env.SUBSCRIBE_API_URL and exposes it as siteConfig.customFields.apiUrl . The homepage EmailSignup component POSTs to ${apiUrl}/subscribe . Wiring the API Gateway endpoint into the Pages env var means the frontend always targets the right backend without hardcoding URLs. Preview branch excludes — gh-pages is excluded from preview builds. That branch is the old peaceiris deploy output; it has no package.json and will fail every build attempt. One gap: build_image_major_version (v1 → v3) isn't exposed in the Cloudflare provider v4. I set it via a one-time API PATCH and documented the workaround in iac/pages.tf . Provider v5 adds native support — revisit on upgrade. Zone Security Without the Provider Trap The cloudflare_zone_settings_override resource in provider v4 reads all zone settings during refresh, including Enterprise-only fields that return HTTP 999 on Free plans. That makes terraform apply fail even when your target settings are correct. The workaround: a null_resource with local-exec that PATCHes only the settings we care about: SSL mode: strict Always Use HTTPS: on Minimum TLS: 1.2 , TLS 1.3: on HSTS: 2-year max-age , include subdomains, preload-ready The triggers block hashes the target values so any change re-applies. It's not elegant, but it's reliable on a Free-plan zone. Email Subscribe API The homepage newsletter form needs a backend. The stack: API Gateway HTTP API — POST /subscribe , GET /confirm?token=... Lambda — validates email, stores pending token in DynamoDB, sends confirmation via SES DynamoDB — subscribers table + tokens table with TTL for expired confirmations SES — domain-verified sending from scotthavird.com All tagged with Project = scotthavird-com and environment-scoped naming ( scotthavird-prod-* ). The double opt-in flow matters: we don't add addresses to the list until the user clicks the confirmation link. Tokens expire via DynamoDB TTL. What I Deliberately Didn't Codify www → apex redirect — Cloudflare Pages owns the http_request_dynamic_redirect ruleset for custom domains. Zone-level Rulesets API tokens can't override it. The fix is documented in Your Cloudflare Pages Redirect Is Probably Backwards : set the apex as the primary custom domain in Pages, then add a Page Rule for belt-and-suspenders. GitHub Actions deploy — Retired. Cloudflare Pages builds directly from the repo. One less moving part, preview URLs on every PR, and no GITHUB_TOKEN deploy secret to rotate. Operating It cd iac terraform plan -var-file = prod.tfvars terraform apply -var-file = prod.tfvars Prod and dev workspaces share the pattern; DNS records for SES are prod-only ( local.is_prod ) to avoid conflicts. Site-side guardrails run in CI on every PR: yarn ci # lint:posts → update:llms → build → validate:schema Infrastructure changes and content changes can ship in the same PR when needed — but they're reviewed separately because they touch different directories. Lessons Codify the stuff that breaks silently. Redirect direction and Node version don't fail loudly until SEO or previews are already damaged. Build-time env vars for frontend API URLs. Hardcoding API Gateway endpoints in React is a deploy-order nightmare; Pages env vars solve it cleanly. Provider limitations are real. When the Terraform resource can't express what you need, document the out-of-band step and add a trigger or comment so the next person doesn't "fix" it back to broken. Keep the site and the infra in one repo. Docusaurus content and Cloudflare/AWS resources share a lifecycle. One PR can add a feature and the API it needs. Related Posts Your Cloudflare Pages Redirect Is Probably Backwards — The www/apex trap that motivated part of this work Ways of Working at the Speed of Thought — Why reducing deploy friction matters when engineers ship in hours This article was created with the help of AI. Originally published at scotthavird.com . Follow me on X and GitHub .

  • HTML All The ThingsPodcastsAudioListen

    The Problem With Putting All Your Tech in One Basket

    Microsoft 365 went down, leaving users struggling to access emails, files, and communication tools. But the bigger question is: are we putting too many eggs in one basket? In this edition of the Web News, Matt and Mike discuss the risks of relying on centralized software…

  • Hacker News Front PageThe Giantsread at source

    Tech Companies Are Trying to Shift the Concept of Privacy (Again)

  • Hacker News: Show HNLibraries, Frameworks, etc.read at source

    Show HN: Gamma PDF – AI-native PDF reader, self-hosted

    Comments

  • Flavio CopesMore Front-end Bloggersread at source

    How to use Fable as the orchestrator and Opus as the executor in Claude Code

    Run Claude Code with Fable 5.2 planning and reviewing while Opus 5.5 sub-agents do the work: the setting, the prompt, and what a real job cost me.

  • Hacker News: Show HNLibraries, Frameworks, etc.read at source

    Show HN: Free Dictionary API – Wiktionary data, no API key required

    Comments

  • SitePointThe Giantsread at source

    Logging AI Prompts and Responses in Java Without Leaking Sensitive Data

    null Continue reading Logging AI Prompts and Responses in Java Without Leaking Sensitive Data on SitePoint .

  • SitePointThe Giantsread at source

    Your SSL certificates can now last 200 days at most: The real risk isn’t renewal

    SSL certificates now last 200 days at most, dropping to 47 by 2029. See why automated renewals still fail quietly and how to monitor certificates before they expire. Continue reading Your SSL certificates can now last 200 days at most: The real risk isn’t renewal on SitePoint .

  • Hacker News: Show HNLibraries, Frameworks, etc.read at source

    Show HN: EDNA – 100% on-device human sensing so AI can perceive the user

    Comments

  • Hacker News: Show HNLibraries, Frameworks, etc.read at source

    Show HN: Podcast News

    Comments

  • Hacker News Front PageThe Giantsread at source

    Monkey Island: all 13 versions side by side

  • Hacker News: Show HNLibraries, Frameworks, etc.read at source

    Show HN: Back endskills – agent skills for safer auth, data and migration code

    Comments

  • Hacker News Front PageThe Giantsread at source

    Nvidia allegedly engineered scarcity by funding AI startups to buy its GPUs

  • Hacker News Front PageThe Giantsread at source

    Ggml v1.0.0

  • Hacker News Front PageThe Giantsread at source

    Elephants found to be increasingly isolated leading to fractured social networks

Friday, 13 November 2026

  • AbduzeedoMulti Author Blogsread at source

    Circuit: Civic Shuttle Brand Identity by The Collected Works

    The Collected Works shapes a civic brand identity for electric shuttle service Circuit with Stadt type, transit arrows, and fleet wraps. Fifty cities meant fifty slightly different versions of Circuit...

  • AbduzeedoMulti Author Blogsread at source

    Inside Ardor Retro Computer’s Phosphor CRT UI/UX Design

    Viacheslav Sheikin’s UI/UX design for Ardor Retro Computer stages an AI cloud agent on an 8-color phosphor CRT, featured on Minimal Gallery. Pressing Escape skips the ASCII boot sequence. Designed and...

  • AbduzeedoMulti Author Blogsread at source

    Porto Rocha Unveils Almeida & Dale Brand Identity

    Porto Rocha builds the Almeida & Dale brand identity on Diakritik AD, a custom typeface, and one strong blue for Brazil's biggest gallery. The blue arrives before anything else. Porto Rocha paints...

  • SitePointThe Giantsread at source

    Best Ecommerce Platforms for Developers: Six Options and the Layers Each Leaves You

    null Continue reading Best Ecommerce Platforms for Developers: Six Options and the Layers Each Leaves You on SitePoint .

  • Flavio CopesMore Front-end Bloggersread at source

    How to audit your CLAUDE.md with /doctor prompt-audit

    Claude Code's /doctor prompt-audit finds stale facts, contradictions and dated wording in CLAUDE.md, AGENTS.md and your skills. I ran it on this site's repo.

  • SitePointThe Giantsread at source

    Running an AI Agent on a Local LLM: What I Measured on One GPU

    null Continue reading Running an AI Agent on a Local LLM: What I Measured on One GPU on SitePoint .

  • Engineering at MetaCompany/Startup Blogs5 min read

    Cuttlefish on Mac: Running Android’s Virtual Device Framework Natively on Apple Silicon

    How Meta's Reality Labs brought Cuttlefish and its QEMU backend to macOS and Apple silicon. [...] Read More... The post Cuttlefish on Mac: Running Android’s Virtual Device Framework Natively on Apple Silicon appeared first on Engineering at Meta .

  • Dave RupertTop Front-end Bloggersread at source

    Conventional Commit rules everything around me

    There’s a community standard out there called Conventional Commit for structured git-commit messages. If you don’t know about it already, it recommends a strict type(scope?): description format for describing a code change in a repo. A normal git commit history might look like this: > git log --oneline 9d30ff6 fix typo 3062496 oops d0b38ad shit b5f8df7 redesign site That’s all well and good, but lacks a bit of structure and detail for a big project with lots of contributors. That’s where Conventional Commit comes in. Instead of a git-commit message like add login page , it might look like this: feat: add user login endpoint Or you can “scope” it to a particular section of your application: feat(auth): add user login endpoint There’s even a ! flag to signal a breaking change to your coworkers: feat!: remove all authentication API endpoints The predefined conventional commit types cover most types of changes: fix: , feat: , chore: , docs: , style: , refactor: , perf: , test: , build: , and ci: . I find these cover most situations but I’m also a bad boy and like to break rules, so I’ll throw in custom types like wip: , a11y: , hotfix: , or an rm: (as a treat) when I feel it adds clarity to the work. But why would anyone voluntarily conform to a standard like this? My answer is… a feeling . Look at our git-log history now: > git log --oneline 9d30ff6 fix(input): restore focus state on input 3062496 style(checkbox): update tokens to tokens v2 d0b38ad chore: update dependencies via dependabot b5f8df7 feat(auth): add user login endpoint ... In a noisy repo that’s increasingly getting noisier (thanks, robots) anywhere you can add predictability is a net-positive. The cumulative effect over time is that you have a highly-scannable, uniform history of what’s happening in your project. Conventional Commit can even help with code review. A style: fix that adds dozens of npm packages should be a signal that you need to break up the work. Types might also inform if you route all a11y: commits to the local expert for code review. And a refactor! breaking change should signal coworkers to be extra-cautious in review and may trigger other process-oriented workflows like broadcasting the upcoming breaking change to anyone in the blast radius. And because it’s a community standard, like the Custom Element Manifest , you can build tooling around it like commitlint . As its name implies, commitlint is a linter that gates all commit messages from your entire team to ensure they abide in the type(scope): description format. I personally tend to avoid adding extra tooling to enforce simple conventions, but I might change my mind on this because the benefits start compounding. If my commits were all similarly formatted, I could also automate our entire changelog and semantic versioning bumps for releases. fix: = PATCH feat: = MINOR any!: = MAJOR Of course, Conventional Commit and Semver itself aren’t perfect but it adds a degree of predictability about the impact of a change from the description alone. Abiding in the Conventional Commit format is a small micro-adjustment to my process, but it has potential to positively impact the entire project and I like those sorts of zero-dollar improvements. Extending Conventional Commit beyond commits One place you’ll also want to extend conventional commit to is pull request titles . Not technically a git-commit message, but if you squash and merge commits the PR title tends to become the commit message by default. Preferring or enforcing conventional commit in pull request titles helps preserve our pristine commit history. If you’re doing pull request titles, why not use them for issue titles too: #123 > bug(input): required focus indcator missing #122 > feat(checkbox): update tokens to v2 #112 > chore: update dependencies from depdendabot #106 > feat(input): make input more engaging There’s harmony when the issue and the solution are matching. Having the type in the issue title sets a clear deliverable; a bug: needs a fix: to resolve it. Consider these duplicate issues for the same bug: #189 > 4.2.7 Focus Visible [bug] [components] [severity:HIGH] #210 > bug(input): focus indicator is missing Which one would get picked up first? I’d argue that even with labels like [bug] and [severity:HIGH] that the second one would be easier to fix because it gives the developer almost all the information they need to fix the issue. It makes the issue a little more actionable and that’s what you want. If every issue is an investigation, nothing gets done. Triaging issues takes cognitive bandwidth . Labels are great at grouping and providing queryable views, but when scanning a list of issues pairing both the tag and the title to determine the ask adds an extra cognitive tax. I’m projecting here, but uniform data in your PRs and issue queues could also allow you to collect stats on which components or areas of your application are the most buggy and expensive to maintain. It can tell you who’s getting saddled with all the bugs or which issue filer is adding too much feature debt. And it can help your team quantify your recurring maintenance tasks that might be hiding because it gets rolled into other work. That might be valuable to an organization. Unconventional usage of Conventional Commit Now let’s extend beyond the practical. I’m finding the Conventional Commit format to be so useful, I’ve started rolling them out to a lot of different places (surprise, coworkers!). One example is our folder full of random scripts/ in the monorepo. What was a randomized list of dozens of scripts and tests… scripts/ ├── docs-tokens.mjs ├── playwright-cli.mjs ├── storybook-compat-table.mjs ├── style-dictionary.mjs ├── sync-fluent-fluent-custom-elements-manifest.mjs ├── validate-themes.mjs └── visual-review-harness.mjs Can become an organized paradise of co-located responsibility: scripts/ ├── build/ │ └── themes-style-dictionary.mjs ├── docs/ │ ├── storybook-generate-compat-table.mjs │ ├── tokens-generate-table.mjs │ └── sync-fluent-custom-elements-manifest.mjs └── test/ ├── playwright-cli.mjs └── playwright-visual-review-harness.mjs └── themes-validator.mjs I’ve found those Conventional Commit types tend to map well to areas of responsibility for repo-level scripts. Manage docs, tests, build tasks, and so on all fit under the Conventional Commit umbrella and it adds some much needed organization to the junk drawer of copy-pasta and generated helper scripts. And if your scripts/ folder is following the Conventional Commit format… why not roll that out to your scripts in package.json : { "scripts": { "docs:generate": "node ./scripts/docs/generate-storybook-compat-table.mjs && node ./scripts/docs/generate-storybook-tokens-table.mjs", "build:themes": "node ./scripts/build/themes-style-dictionary.mjs", "test:themes": "node ./scripts/test/themes-validator.mjs" } } Built-in npm features like pre* and post* hooks mess up our perfect naming system a bit. A prebuild:themes task reads fine but predocs:generate is a bit marble-mouthy. But that’s an eye-twitching discrepancy I’m willing to accept to abide in what npm gives me for free. Then… if you’ve added Conventional Commit to your scripts/ and your "scripts" and are living that agentic coding life, why not apply the same organization principle to your skills/ folder? skills/ ├── build/ │ ├── themes/SKILL.md ├── docs/ │ ├── component-jsdoc/SKILL.md │ ├── storybook/SKILL.md │ └── technical-writing/SKILL.md └── test/ ├── playwright-tests/SKILL.md ├── visual-tests/SKILL.md └── writing-tests/SKILL.md This looks great… it falls apart in the real world. Skills installed from the internet don’t abide in this format. Having some skills nested and others not creates a feeling of unease, so a flatter folder structure for skills is probably better. That said, it’s not uncommon to need a skill to inform your model about your repo-level scripts and those are places you can still maintain parity. skills/ ├── build-themes/SKILL.md ├── docs-storybook/SKILL.md ├── docs-components/SKILL.md ├── docs-technical-writing/SKILL.md ├── grill-me/SKILL.md ├── i-have-adhd/SKILL.md ├── test-playwright/SKILL.md ├── test-visual-review/SKILL.md └── test-writing/SKILL.md While applying Conventional Commit to your skills/ folder is a bit impractical, one area I can confirm it does help is organizing your agent chats. Fire off a handful of agents and it can get confusing about which one is doing what task, even with their autogenerated chat label. I’ve found it super helpful to ask your bot to rename its chat using the Conventional Commit format. Try it out and bask in the uniform list of tasks. To get this to work consistently in the GitHub Copilot app, I had to modify my session prompt in Sessions > App instructions: At the start of every new chat, before answering my first request, call `rename_session` using `type(scope): description`. Do this even for non-coding chats. Rename only once unless I ask otherwise. I’m not sure how it works in your preferred agent manager, but I assume you could write a skill or put it in your AGENTS.md , but I’d have a conversation with your coworkers first before codifying your obsessive-compulsions in the project repo. Join me in my obsession You might have read all this and said, “This is a man who –in a world of chaos– is looking to over-manage a small thing like title text so that he can feel in control of his own life!” and to that I’d say… Probably. I like to think I’ve just hit the point in my life where I don’t want to spend an single brain cell thinking about how I should format title text or name a file. I wasn’t this passionate about Conventional Commit a year ago, I think I got radicalized. Generative AI almost certainly plays a big part where every robot names files and fixes different every time. That’s built-in to its dice-roll mechanic. Knowing there’s a chaos agent in the mix, I feel a need to find low-hanging fruit for consistency and (for right now) this feels pretty good to me.

  • AbduzeedoMulti Author Blogsread at source

    How to Make a Rotating 3D Cube Text Animation in ascente.design

    Learn how to build a looping Instagram Story where lines of text rotate around a 3D cube, one row at a time, using Drum wrap in ascente.design. Reading time: about 10 minutes · Level: beginner-friendl...

  • AbduzeedoMulti Author Blogsread at source

    Inside the Craft of the Nubank Brand Refresh by Koto

    Koto's Nubank brand refresh turns a 140-million-customer bank into one flexible system: purple, modular, and unmistakably Nu. Nubank started in Brazil with a simple idea, that banking did not need to ...

  • AbduzeedoMulti Author Blogsread at source

    Twice Shy’s Tactile Soap Packaging Design for Tula Louise

    Twice Shy’s packaging design for London soap atelier Tula Louise pairs translucent vellum wraps, metal clips, and 12 apothecary outlines. Opaque cartons hide the best part of a natural soap bar. Jowan...

  • SitePointThe Giantsread at source

    10 Best AI App Builders I've Used in 2026 (and What Each One Gets Wrong)

    We built the same app on 10 AI app builders and compared pricing, backend setup, permissions, code ownership and the costs of later edits. Continue reading 10 Best AI App Builders I've Used in 2026 (and What Each One Gets Wrong) on SitePoint .

  • CSS-TricksThe Giantsread at source

    10 Big Ol’ 2027 Black Friday Deals

    A big ol' roundup of Black Friday deals on front-end courses from the best independent publishers and educators in the business. 10 Big Ol’ 2027 Black Friday Deals originally handwritten and published with love on CSS-Tricks . You should really get the newsletter as well.

  • AdactioTop Front-end Bloggersread at source

    The speakers at #FFconf have such excellent taste!

  • Darek KayMore Front-end Bloggersread at source

    #0198

    An ICM photo that looks like a painting. Golden leaves under a pergola are lighted by the sun.

  • Jeffrey Zeldman PresentsMore Front-end Bloggers1 min read

    Diggs This

    RZA of Wu-Tang Clan has invested in AYO Music Group, the music copyright company co-founded by Tracklib’s Pär Almqvist and clearance veteran Deborah Mannis-Gardner. AYO helps rightsholders get more out of their catalogues. Bobby Digital is in the building. Pär (AKA Peyo) Almqvist is a magical creative being and my Swedish brother. If past lives […] The post Diggs This appeared first on Jeffrey Zeldman Presents .

  • SitePointThe Giantsread at source

    Automating Contract Signing in Node.js: Webhooks, Verification, and Storing Signed PDFs

    null Continue reading Automating Contract Signing in Node.js: Webhooks, Verification, and Storing Signed PDFs on SitePoint .

  • Net NinjaYouTube ChannelsVideoWatch on YouTube

    "Anti-Slop" Designs with Impeccable (a Crash Course) #3 - Full Page Redesign

  • HeyDesignerDeveloper/Designer Newsread at source

    Design Zeitgeist

    Designing with HTML, Where the disabled button got its rule, Computing with CSS layout.

  • PiccalilliMore Front-end Bloggersread at source

    The Index: Issue #206

    CSS Golf A fun spin on CSS challenges here where you try to fix an issue in as little "strokes" as possible. FaceTypes As the strap-line says, a collection free fonts that are actually worth using. I made a weird web page every single day in October and lived to tell the tale A nice write-up from Jenn with some very sage advice for people using LLMs a lot for their development work. Open source says no A collection of open source projects that have explicitly banned AI contributions. Big walk used AI in 'the final stretch' of development, kicking off intense awards debate This caused quite the discourse on Bluesky 😬 Some little ways I’m using CSS :has() in the real world Here's one from the Piccalilli archives that you might have missed to wrap up this issue. P.S. this is a good website from personalsit.es . Sponsor message JavaScript for Everyone has a huge new update! Mat Marquis has been hard at work to create 3 new modules, 20 new lessons — including practical exercises — and 13 re-worked lessons. It's a lot of good new stuff and people that have previously purchased the course get all of this for free ! Use the link here to save 20% off your purchase. Get the course and save 20%

  • SitePointThe Giantsread at source

    How to Migrate an Elementor Site to the WordPress Block Editor

    null Continue reading How to Migrate an Elementor Site to the WordPress Block Editor on SitePoint .

  • Flavio CopesMore Front-end Bloggersread at source

    How to send email properly, for developers and AI agents

    Subdomains, SPF, DKIM, DMARC, alignment, the message itself, bounces and abuse, with the real records behind flaviocopes.com and the rules I give an AI agent that sends email.

  • SitePointThe Giantsread at source

    What is Model Routing in AI?

    null Continue reading What is Model Routing in AI? on SitePoint .

  • ESLint BlogLibraries, Frameworks, etc.2 min read

    ESLint v10.15.0 released

    Highlights Faster config resolution This release includes an updated version of @eslint/config-array with a faster implementation of config resolution. This is the step in which ESLint decides, for every file and directory it visits, whether the path is ignored and which objects…

  • ESLint BlogLibraries, Frameworks, etc.3 min read

    Retiring the contributor pool

    Back in 2022, we shared our plan to pay all contributors for non-trivial contributions to ESLint. Our belief was that all contributions of a certain size are valuable and it didn’t make sense to pay team members for their pull requests and not pay anything for work done by…

Thursday, 12 November 2026

  • AbduzeedoMulti Author Blogsread at source

    Blæst: Technical Outerwear Visual Identity by Kurppa Hosk

    Kurppa Hosk shapes a wind-driven visual identity for Norwegian rainwear label Blæst with blown grotesque type, a vortex mark, and retail tags. Blæst takes its name from the Norwegian word for strong w...

  • Level AccessCompany/Startup Blogs7 min read

    From Policy to Practice: How to Put Your Accessibility Policy to Work

    To turn your accessibility policy into practice, translate it for each team, name owners, embed guidance in workflows, and prioritize user impact. Your The post From Policy to Practice: How to Put Your Accessibility Policy to Work appeared first on Level Access .

  • AbduzeedoMulti Author Blogsread at source

    Branding: Alpha Bank by Pentagram and Dalziel & Pow

    Alpha Bank has unveiled a major transformation of its brand identity and retail branches, combining work by Pentagram and Dalziel & Pow. Visiting a retail bank branch rarely tops anyone’s weekend ...

  • Mux BlogCompany/Startup Blogs4 min read

    Mux Robots, now in your living room

    Build richer mobile and TV video apps with the Mux React Native Player, featuring Mux Robots summaries, chapters, key moments, and remote-friendly controls.

  • Google for DevelopersYouTube ChannelsVideoWatch on YouTube

    Building with Gemini in Google Antigravity

  • CSS-TricksThe Giantsread at source

    Beyond 12 Columns: Designing Layouts With Personality

    Too many websites look alike. They use familiar layouts, repeat the same patterns, and often leave little impression once you’ve moved on. Andy Clarke explores how understanding a company’s story can lead to more distinctive designs, using modular and compound grids to create layouts with character. Beyond 12 Columns: Designing Layouts With Personality originally handwritten and published with love on CSS-Tricks . You should really get the newsletter as well.

  • Web Tools WeeklyMulti Author Blogsread at source

    Web Tools Weekly Issue #695

    CSS/HTML, Testing, Media Tools

  • Flavio CopesMore Front-end Bloggersread at source

    How to try open-weight models through OpenRouter

    Compare open-weight models from JavaScript through OpenRouter, inspect current prices and token usage, and decide what deserves a local download.

  • The Mozilla BlogBrowsers, engines, etc.5 min read

    An open letter to every family’s designated IT support

    Almost every family has one. They’re the only ones who know which remote turns on the TV and which controls the volume and channels. They know what an HDMI cable actually does and where to plug it in. They’ve even fixed multiple phone issues within seconds through a little-known, well-kept secret procedure (turning it off […] The post An open letter to every family’s designated IT support appeared first on The Mozilla Blog .

  • Net NinjaYouTube ChannelsVideoWatch on YouTube

    "Anti-Slop" Designs with Impeccable (a Crash Course) #2 - Critique Current Designs

  • DXDMore Front-end Bloggersread at source

    O design como proposta de valor de uma startup

    A Web Summit como mostra também do papel que o design nas suas mais variadas vertentes pode ter no crescimento do negócio de uma startup. O conteúdo O design como proposta de valor de uma startup aparece primeiro em DXD .

  • Flavio CopesMore Front-end Bloggersread at source

    AWS Emulator: a local AWS for you and your coding agents

    AWS Emulator runs the AWS APIs on your machine, with no account. How to run it on a Mac, and why it's a good test loop for coding agents.

  • Flavio CopesMore Front-end Bloggersread at source

    What's defensible for small builders now that AI labs ship apps

    Anthropic and OpenAI now ship the apps their customers build. What a small builder can still defend: niche data, workflows, trust and distribution.

  • Flavio CopesMore Front-end Bloggersread at source

    Muse Ember vs Claude Haiku 5.5 vs GPT-6 Luna on a real app job

    Three small AI models at the same price, $0.10 and $0.50 per million tokens, tagging 200 blog posts. Accuracy, latency and cost compared, with the script.

  • Smashing MagazineThe Giants15 min read

    Should You Actually Add AI To That? A Four-Question Audit For Product Teams

    An AI feature can save users time on a task, only for them to spend it checking the results. This practical audit helps product teams decide where AI earns its place and what users need to verify its output.

  • Adam ArgyleTop Front-end Bloggersread at source

    WWW Ep260 Will AI Kill Us All Jev Says 87

    Ep #260 Will AI Kill Us All? Jev Says: 87% Robbie and I sip Courage & Conviction, talk Jev, gates that skip the LLM slop, the paperclip problem , model degradation and thinking levels, Ocarina of Time remake vs. digital ownership, and an arrow through the living room window.…

See everything from the last 30 days →

Articles belong to their publishers. This site only collects what their feeds provide.

Updated 14 November 2026 at 14:01