开发者
I Built a Unit Converter in Pure Vanilla JS — 7 Categories, 70+ Units, 165 Tests, Zero Dependencies
Unit converters are everywhere online, but they all seem to either require an account, run ads that cover half the screen, or send your input to a server for no reason. I built one that runs entirely in your browser, with no dependencies, no tracking, and no round-trips. 👉 https://unit-converter-dev.pages.dev What It Does Seven conversion categories, 70+ units, real-time bidirectional conversion: Category Example units Length mm, cm, m, km, in, ft, yd, mi, nmi, light-year Weight mg, g, kg, t, oz, lb, st, short ton Temperature °C, °F, K, °R Volume ml, l, m³, fl oz, cup, pint, quart, gallon, tbsp, tsp Area mm², cm², m², km², ha, acre, ft², in², mi², yd² Speed m/s, km/h, mph, ft/s, knot, Mach Data bit, byte, KB/KiB, MB/MiB, GB/GiB, TB — both SI and binary Features: Bidirectional — type in either field, the other updates instantly Swap button — flip from/to with one click All-units panel — see your input converted to every unit in the category simultaneously Formula display — shows the conversion factor (e.g. "1 Mile = 1.609344 Kilometer") Zero dependencies — single HTML file, no build step, no npm Implementation Notes Linear vs. non-linear conversions Most unit conversions are linear: multiply by a factor to get to the base unit, divide by another factor to get to the target. The approach: function convert ( catKey , fromUnit , toUnit , value ) { const base = toBase ( catKey , fromUnit , value ); // → base unit return fromBase ( catKey , toUnit , base ); // base unit → target } function toBase ( catKey , unit , value ) { const u = CATEGORIES [ catKey ]. units [ unit ]; if ( u . toBase ) return u . toBase ( value ); // non-linear (temperature) return value * u . factor ; } Temperature is the classic non-linear case. You can't just multiply to convert between Celsius, Fahrenheit, and Kelvin — you need offset arithmetic: temperature : { units : { C : { toBase : v => v + 273.15 , // °C → K fromBase : v => v - 273.15 , // K → °C }, F : { toBase : v => ( v - 32 ) * 5 / 9 + 2
AI 资讯
I Built a QR Code Generator in Pure Vanilla JS — No Libraries, No Server, 202 Tests
QR codes look like magic — a grid of black and white squares that encodes anything from a URL to a business card. But how do they actually work? I decided to find out the hard way: implement the full QR Code Model 2 algorithm in vanilla JavaScript, zero external dependencies. The result: QR Code Generator — a free, client-side tool that generates QR codes from any text or URL. 👉 https://qr-code-generator-e83.pages.dev Why No Libraries? I maintain a collection of browser-only developer tools at devnestio . Every tool has the same rule: zero external dependencies. No npm installs, no CDN scripts, no servers. For most tools (JSON diff, Base64 encoder, UUID generator) that's easy. QR codes are different. The spec is a 126-page ISO document. Most developers just npm install qrcode and call it a day. But writing it from scratch taught me more about error-correcting codes, Galois field arithmetic, and matrix encoding than I ever expected. Worth every hour. What the Tool Does Real-time generation as you type (debounced at 80ms) Size selector — 128 × 128, 256 × 256, or 512 × 512 pixels Error correction level — L (7%), M (15%), Q (25%), H (30%) Color picker — any foreground and background color PNG download via canvas SVG download with crisp vector output at any scale How QR Codes Actually Work QR Code Model 2 (the standard you see everywhere) has six major steps. Here's the short version: 1. Data Encoding Text gets encoded into one of three modes based on content: Numeric ( 0-9 ): packs 3 digits into 10 bits — most compact Alphanumeric ( 0-9 A-Z $%*+-./:space ): 2 chars into 11 bits Byte (everything else): UTF-8, one byte per 8 bits The encoder picks the mode automatically and finds the minimum QR version (1–40) that fits the data. function detectMode ( text ) { if ( /^ \d +$/ . test ( text )) return NUMERIC_MODE ; if ( text . split ( '' ). every ( c => ALPHANUMS . includes ( c ))) return ALPHANUM_MODE ; return BYTE_MODE ; } 2. Reed-Solomon Error Correction This is the hard
AI 资讯
60 Themes, 51 Components, still 0 Dependencies. Yumekit v0.5 Released!
Back in May we here at Waggy Labs launched the beta release of our Web Component UI kit " Yumekit ". Yumekit is a pure web component UI toolkit. Upon its release, it was comprised of roughly 36 fully styled and fully functional UI components that work with just about every web architecture straight out of the box. No configuration or setup necessary, all one needs to do is include the Yumekit script (using either a CDN or installed through NPM) and start building. All components come styled out of the box with no need to include any style sheets. Last week, we launched version 0.5. With this latest release, that job is being made easier with the inclusion of new components that add several layout options as well as new Data, Navigation, and Utility components, bringing the total number of components to 51. For us, this toolkit has provided us a framework-agnostic solution for our internal tools as well as any client projects. With over 60 themes spread over 9 well-known (and some brand new) open source Design Systems all built directly into the library, we have plenty of options available to us to keep our designs fresh without needing to spend hours dealing with CSS. It's light-weight, dependency free, and well documented. New in 0.5 Animate The y-animate component allows you to animate entrances and exits for nested components using a few simple configuration attributes. Code The y-code component allows you to display formatted and colorized code, as well as providing a few easy and convenient ways for your users to copy the provided code. Help The y-help component provides a tutorial experience for users of your application with minimal configuration. Simply provide the elements to be highlighted, the messages to be shown, and it handles the rest! Paginator y-paginator provides a configurable set of pagination buttons to help your users navigate through large data sets. Sidebar We had originally included a y-appbar component (which we still do) that had a "Sideba
AI 资讯
How to Detect Which Font Is Actually Rendering in a Browser (Not Just the CSS Stack)
getComputedStyle(element).fontFamily returns the CSS declaration: "Hiragino Kaku Gothic ProN", "Yu Gothic", "Noto Sans JP", sans-serif . That's not the font that rendered. It's a priority list. The browser picks the first one that's available and contains a glyph for the character being rendered. For Latin text, this distinction usually doesn't matter — Windows, macOS, and Linux have converged on a small set of common system fonts. For Japanese, it matters enormously. The visual weight, stroke contrast, and letterform style of Hiragino, Yu Gothic, and Noto Sans JP are genuinely different. A site designed on macOS (where Hiragino is the system Japanese font) looks different on Windows (where Yu Gothic is the fallback). Here's how to figure out what's actually rendering, and what I learned building Japanese Font Finder to automate it. Why getComputedStyle Doesn't Answer the Question getComputedStyle(el).fontFamily gives you the cascade result — what the browser received after applying all CSS rules. But it doesn't tell you which entry in the stack was selected. The underlying question is: does this font exist on this system, and does it have a glyph for this specific character? For Japanese, both conditions matter. A font might exist on the system but only cover a subset of kanji (common with CJK fonts that split across multiple files). The browser will use that font for characters it covers, and fall back for others. Canvas-Based Font Detection The classical technique uses a <canvas> element to measure text rendered with each font in the stack: function getFallbackWidth ( canvas , char ) { const ctx = canvas . getContext ( ' 2d ' ); ctx . font = `16px monospace` ; // known-available baseline return ctx . measureText ( char ). width ; } function testFont ( fontName , char ) { const canvas = document . createElement ( ' canvas ' ); const ctx = canvas . getContext ( ' 2d ' ); ctx . font = `16px " ${ fontName } ", monospace` ; return ctx . measureText ( char ). width ; }
开源项目
🔥 googleapis / google-cloud-node - Google Cloud Client Library for Node.js
GitHub热门项目 | Google Cloud Client Library for Node.js | Stars: 3,181 | 0 stars today | 语言: JavaScript
开源项目
🔥 worldwonderer / oh-story-claudecode - 网文/小说写作 skill 包,覆盖长篇与短篇网络小说的扫榜、拆文、写作、去AI味、封面图全流程
GitHub热门项目 | 网文/小说写作 skill 包,覆盖长篇与短篇网络小说的扫榜、拆文、写作、去AI味、封面图全流程 | Stars: 3,165 | 51 stars today | 语言: JavaScript
开源项目
🔥 Neet-Nestor / Telegram-Media-Downloader - A script allowing you to download images and videos from Tel
GitHub热门项目 | A script allowing you to download images and videos from Telegram web even if the group restricts downloading. | Stars: 4,656 | 69 stars today | 语言: JavaScript
AI 资讯
UTC, GMT, and the time zone bugs that keep biting developers
Time zones are one of those topics that look simple until you ship something and a user in another country sees the wrong time. Here are the traps I keep seeing, and how to reason about them in 2026. UTC is not a time zone, and GMT is not UTC UTC (Coordinated Universal Time) is a time standard, not a region. GMT is a time zone that happens to share the same offset as UTC most of the year. For storage and math, always think in UTC. Treat GMT as just another named zone. Rule 1: store timestamps in UTC Store every instant as UTC (or an epoch value). Convert to a local zone only at the edges, when you display to a user. If you store local times, you will eventually lose the offset and never recover the true instant. Rule 2: an offset is not a zone +09:00 tells you the offset right now. It does not tell you the zone, because zones change offset across the year due to daylight saving time. Store the IANA zone name (like America/New_York ), not just the offset. The offset is derived from the zone plus the date. Rule 3: DST is where it hurts The same wall-clock time can happen twice (fall back) or never (spring forward). Scheduling "9am every day" is a zone-aware operation, not an offset-aware one. Libraries like the built-in Intl.DateTimeFormat and Temporal (now widely available) handle this correctly if you give them a zone name. new Intl . DateTimeFormat ( ' en-US ' , { timeZone : ' Asia/Tokyo ' , dateStyle : ' short ' , timeStyle : ' short ' , }). format ( new Date ()); Rule 4: scheduling across teams is an overlap problem For a distributed team, the useful question is not "what time is it there" but "when do our working hours overlap". That is a set-intersection over each person's 9-to-5 expressed in UTC. A tool for the human side When I just need to eyeball overlaps and pick a meeting time without writing code, I use the free tool I built: ZonePlan , a time zone meeting planner and live world clock. If you want the practical playbook for picking meeting times, I wrote
AI 资讯
I hooked up Trading212 to Home Assistant and now Alexa tells me if I'm up or down every morning
I've been using Home Assistant for a few years and Trading212 for longer than that. It was inevitable these two things would end up connected. The Trading212 API is surprisingly good — portfolio value, individual positions, pies, dividends, all there. So I wrote a custom integration to pull it all into HA as sensors, then a Lovelace card to make it actually look decent on a dashboard rather than a wall of entity rows. The card does zero-config auto-discovery which was the bit I spent the most time on. You drop it on a dashboard and it finds your sensors automatically — no copying entity IDs, no manual config unless you want it. Five card types: portfolio overview with a sparkline, scrollable positions list, pies with goal progress, and a combined one if you want everything in one card. The sparkline was fiddly. HA's recorder only writes state changes, not regular samples, so if your portfolio value is flat between polls the chart has gaps. Had to smooth over those client-side. The part I use most though is the automations. Every weekday at 8am Alexa tells me where I stand: action : - action : notify.alexa_media_kitchen data : message : > Portfolio is worth {{ states('sensor.trading212_total_value') | float | round(0) | int }} pounds. Today you are {% if states('sensor.trading212_pnl_today') | float >= 0 %}up{% else %}down{% endif %} {{ states('sensor.trading212_pnl_today') | float | abs | round(2) }} pounds. data : type : tts And Friday at 6pm I get the weekly version with P&L for the week and which position moved the most. I like that it just tells me — if the market's had a bad week I'd probably avoid opening the app, but Alexa doesn't give me the option to ignore it. Both the integration and the card are on GitHub. The card is in HACS as a custom repo while it waits for default catalogue approval: https://github.com/Smart-Home-Assistant-UK/lovelace-trading212-card I wrote up the full setup with all the automation YAML here if you want to copy the whole thing: ful
开发者
I built a free whale tracker for Polymarket — here's what I learned
The problem: I kept missing big moves on Polymarket because I had no way to see what the biggest traders were betting on in real time. So I built WhaleTrack — a free, no-signup tool that shows you exactly what top Polymarket whales are buying and selling. What it does Live whale activity feed — see the last 40 trades from top wallets, updated on refresh Whale leaderboard — P&L, win rate, trade count for the biggest accounts No login, no ads, no fluff — just the data How it works The whole thing is vanilla HTML/CSS/JS deployed on Vercel with two serverless functions: /api/whales.js — hits the Polymarket leaderboard API, fetches position stats for each whale, calculates win rates from closed positions /api/activity.js — pulls recent trades for each whale wallet in parallel, filters out internal combo transactions (no title / zero price), and returns the 40 most recent trades The serverless layer solves CORS — Polymarket's data API doesn't allow browser requests, so everything goes server-side. Tech stack Frontend: Vanilla HTML/CSS/JS (zero dependencies) Backend: Vercel serverless functions Data: Polymarket public data API Deploy: Vercel (free tier) Biggest lesson Filtering bad data is half the work. The raw API returns combo trades and internal transactions that show up as "Unknown Market @ 0¢" — useless noise. Had to figure out which fields to check (title, price > 0) to strip them. Also: win rate calculation is tricky when most whales have unrealized profits. Showing "—" instead of 0% is more honest. Try it WhaleTrack → Also launched on Product Hunt today if you want to show some love: Product Hunt Built this in a weekend. Happy to answer questions about the Polymarket API or Vercel serverless setup.
产品设计
I Rebuilt Instagram Stories' Segmented Progress Bars
Instagram/WhatsApp Stories have a signature UI: those segmented bars across the top, one filling at a time. It looks fancy but it's a simple pattern. Here's a live, tappable rebuild in vanilla JS + CSS. 📸 Try it (tap left/right, hold to pause): https://dev48v.infy.uk/design/day17-instagram-stories.html The segmented bar One bar per story. The rule: only the active segment animates its width 0→100%; segments before it are full, segments after are empty. When the active one completes, advance to the next and reset the rule. Driving the fill A single requestAnimationFrame loop tracks elapsed time vs the per-story duration (~4s) and sets the active bar's width. On completion → next story. The interactions that sell it Tap the right half = next, left half = previous (split the screen into two zones). Press-and-hold = pause ( pointerdown pauses the timer, pointerup resumes) — so users can actually read. Reset past/future segment states whenever you jump. Why rAF over CSS animation A timer loop makes pause/resume and tap-to-skip trivial — you control the clock. Pure CSS animations are harder to interrupt mid-fill. 🔨 Full build (segments → animate active → advance → tap zones → hold-to-pause) on the page: https://dev48v.infy.uk/design/day17-instagram-stories.html Part of DesignFromZero. 🌐 https://dev48v.infy.uk
AI 资讯
Rust Ate the JavaScript Toolchain. Then Cloudflare Bought It
I run Vite on almost everything. Astro sites, Nuxt projects, a small group of libraries I maintain on the side. The build tool is the part of the stack I think about least, because it just works. So when the thing under all of that changes twice in three months, I read the release notes properly. Here is what actually changed, what breaks, and the part that made developers argue for a week straight. For Five Years, Vite Ran on Two Bundlers When Vite launched, it made a pragmatic bet. esbuild for the dev server, because it is fast. Rollup for production, because its output is well optimized. Two tools, two jobs. It worked. But it had a cost. Two bundlers meant two configs, two sets of quirks, and output that could drift between dev and prod. You tuned one, and the other behaved slightly differently. Vite 8 ends the split. It shipped on March 12 with a single bundler called Rolldown, written in Rust, with the Rollup plugin API on top. Under Rolldown sits Oxc, a Rust parser and transformer that does the TypeScript and JSX work Babel used to do. One language. One pipeline. Dev and prod finally agree. This Is a Pattern, Not a One-Off esbuild (Go) made webpack look slow. Bun did the same to Node for some workloads. Biome replaced Prettier and ESLint and runs many times faster. Now Rolldown does it to Rollup and esbuild at the same time. Every time a core JavaScript tool gets rewritten in a compiled language, the same thing happens. The speed jump is large enough to make the old version look broken. The interesting part is not the speed. It is the compatibility. These Rust tools do not ask you to relearn your stack. Rolldown speaks the Rollup plugin API. Biome follows ESLint and Prettier conventions. The migration is designed to be boring, and boring is the point. The Numbers, With a Grain of Salt The headline figure is real. Linear cut its production build from 46 seconds to 6 . Vite reports builds 10 to 30 times faster than the old Rollup path. Other large projects repor
开源项目
🔥 louislam / uptime-kuma - A fancy self-hosted monitoring tool
GitHub热门项目 | A fancy self-hosted monitoring tool | Stars: 88,449 | 45 stars today | 语言: JavaScript
开源项目
🔥 4ian / GDevelop - 🎮 Open-source, cross-platform 2D/3D/multiplayer game engine
GitHub热门项目 | 🎮 Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone. | Stars: 24,153 | 34 stars today | 语言: JavaScript
AI 资讯
JavaScript Arrays Methods - Part 1
What is an Array? An Array is a special object in JavaScript used to store multiple values in a single variable. Instead of creating separate variables, let student1 = " John " ; let student2 = " David " ; let student3 = " Alex " ; we can use an array: let students = [ " John " , " David " , " Alex " ]; Each value inside the array is called an element , and every element has an index starting from 0 . Index : 0 1 2 ------------------------- Array : | John | David | Alex | ------------------------- 1. Array length Definition The length property returns the total number of elements present in an array. It is not a function . It is a property of an array object. It is also writable, meaning you can change the length to increase or decrease the array size. Syntax array . length To modify the array length: array . length = newLength ; Parameters None. Returns Returns a number representing the total number of elements in the array. Internal Working Consider this array: let fruits = [ " Apple " , " Orange " , " Mango " ]; Memory representation: Index 0 → Apple 1 → Orange 2 → Mango length = 3 When JavaScript creates the array, it internally stores a special property: { 0 : "Apple" , 1 : "Orange" , 2 : "Mango" , length: 3 } Whenever you access: fruits . length JavaScript simply returns the value stored in the length property. It does not count the elements every time. This makes length very fast. Example 1 let fruits = [ " Apple " , " Orange " , " Banana " ]; console . log ( fruits . length ); Output 3 Example 2 - Updating Length let numbers = [ 10 , 20 , 30 , 40 ]; numbers . length = 2 ; console . log ( numbers ); Output [ 10 , 20 ] JavaScript removes the remaining elements. Example 3 - Increasing Length let colors = [ " Red " , " Blue " ]; colors . length = 5 ; console . log ( colors ); Output [ "Red" , "Blue" , empty × 3 ] The new positions become empty slots . Real-Time Example Imagine an E-commerce Shopping Cart . let cart = [ " Laptop " , " Mouse " , " Keyboard " ]; co
开发者
From Financial Services to Full-Stack Dev: My First 3 Months
I spent 13 years in financial services — 7 at Discover Financial, 6 at Bread Financial — consistently finishing in the top 5% of my team. I was good at my job. Really good. But in March 2026, I enrolled in Coding Temple's Full-Stack Web Development bootcamp and started building. Here's what 3 months actually looks like from zero. Month 1: HTML, CSS, and Figuring Out Why Nothing Looks Right I started where everyone starts — HTML and CSS. Built a food landing page (FoodSpot) and a multi-page event site (EventHive). Learned Flexbox, Grid, responsive design, and why box-sizing: border-box should just be the default everywhere. What I shipped: FoodSpot — food landing page EventHive — responsive multi-page event site What I earned: ✅ Web Development with HTML & CSS (Coding Temple verified badge) Month 2: JavaScript, Then Python JavaScript clicked faster than I expected. DOM manipulation, ES6+, event listeners. Then Python — and honestly, Python felt natural. The OOP concepts made sense immediately. What I shipped: Python CLI Task Manager — persistent task app with file storage, OOP, exception handling Defeat the Evil Wizard — text-based RPG with multiple classes, inheritance, combat logic, and game state management What I earned: ✅ JavaScript Mastery ✅ Python Foundations for Software Engineering ✅ Advanced Python Month 3: React React was the biggest jump. Component architecture, hooks, state management, routing. But I got through it by building something real. What I shipped: FakeStore API — a full e-commerce SPA consuming a live REST API with dynamic product rendering, client-side routing, CRUD operations, and loading/error state management What I earned: ✅ Single Page Apps with React What I Brought From Finance That Helped People underestimate what non-tech backgrounds bring to code. Here's what transferred directly: Data analysis → Debugging mindset. I spent years finding patterns in account data. Finding why code breaks is the same muscle. Process optimization → Clean
AI 资讯
How to Stream & Flatten 1GB+ JSON to CSV in the Browser Without Memory Leaks
As developers, data engineers, or analysts, we’ve all been there: you download a massive database export, a logging stack dump, or a transaction archive, only to find it's a multi-gigabyte JSON file. You try to import it into a spreadsheet or run it through a standard online converter, and boom—your browser tab freezes, crashes, or shows the dreaded "Out of Memory" screen. Even worse, if you try to use standard cloud-based online tools, you might have to wait for a 500MB upload to complete, only to hit a rigid file-size cap or, worse, compromise sensitive data privacy by uploading corporate logs or database records to a third-party server. In this guide, we will explore: Why large JSON files crash standard parsers (the V8 heap limit problem). How streaming architectures solve this by reading data chunk-by-chunk. NDJSON (JSON Lines) vs. JSON Arrays and how to stream them. A browser-native, 100% offline tool to convert large JSON to CSV instantly: Parsify's Large JSON Stream Converter . How to implement your own basic browser-based JSON streaming parser in JavaScript. 1. The Anatomy of a Memory Crash (Why JSON.parse Fails) If you are using JavaScript or Node.js, the simplest way to read and parse a JSON file is to load the file into memory and run JSON.parse(). const fs = require ( ' fs ' ); // Naive approach: Will crash on a 1GB+ file fs . readFile ( ' database-dump.json ' , ' utf8 ' , ( err , data ) => { if ( err ) throw err ; // POINT OF FAILURE: V8 Heap Out of Memory const records = JSON . parse ( data ); records . forEach ( record => { // Process record... }); }); This works fine for small config files. But once your JSON file reaches 100MB, 500MB, or 1GB+, this approach is guaranteed to trigger a fatal crash: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory Why does this happen? The String Duplication Overhead: When you load a 1GB file into memory, you first allocate ~1GB of RAM for the raw text string. The
开源项目
🔥 hzm0321 / real-time-fund - 基金实时估值查看
GitHub热门项目 | 基金实时估值查看 | Stars: 1,411 | 43 stars this week | 语言: JavaScript
开源项目
🔥 trekhleb / javascript-algorithms - 📝 Algorithms and data structures implemented in JavaScript w
GitHub热门项目 | 📝 Algorithms and data structures implemented in JavaScript with explanations and links to further readings | Stars: 196,137 | 15 stars today | 语言: JavaScript
开源项目
🔥 PipedreamHQ / pipedream - Connect APIs, remarkably fast. Free for developers.
GitHub热门项目 | Connect APIs, remarkably fast. Free for developers. | Stars: 11,502 | 2 stars today | 语言: JavaScript