AI 资讯
This is how I added an in-browser auto captions feature to my YouTube Shorts converter web application using Whisper AI and ffmpeg.wasm
A few weeks ago I launched Convert to Shorts — a free browser-based tool that converts horizontal videos to YouTube Shorts format (9:16) without uploading anything to a server. I wrote about the ffmpeg.wasm + Vite setup in a previous article. The most requested feature after launch was auto captions. Captions significantly boost Shorts engagement since most people watch without sound, and manually typing captions is tedious. The challenge: how do you add free auto captions to a privacy-first tool that never uploads your video to a server? The answer: run Whisper AI in the browser. The stack - Transformers.js ( @xenova/transformers ) — Hugging Face's JavaScript port of the Transformers library, runs ONNX models in the browser via WebAssembly Whisper tiny — OpenAI's speech recognition model, 75MB, surprisingly accurate for clear speech Web Audio API — for extracting and resampling audio from the video file ffmpeg.wasm — for burning captions into the video ASS subtitles — the subtitle format libass (inside ffmpeg.wasm) understands. Step 1: Audio extraction Whisper expects mono 16kHz audio as a Float32Array. The Web Audio API handles this cleanly: async function extractAudio ( file : File , trimStart : number , trimEnd : number ): Promise < Float32Array > { const arrayBuffer = await file . arrayBuffer (); const audioContext = new AudioContext ({ sampleRate : 16000 }); const audioBuffer = await audioContext . decodeAudioData ( arrayBuffer ); const sampleRate = audioContext . sampleRate ; const startSample = Math . floor ( trimStart * sampleRate ); const endSample = Math . floor ( trimEnd * sampleRate ); // Mix down to mono, slice to trim range const channelData = audioBuffer . getChannelData ( 0 ); const trimmed = channelData . slice ( startSample , endSample ); await audioContext . close (); return trimmed ; } Creating the AudioContext at 16kHz means the browser automatically resamples from whatever the source rate is (usually 44.1kHz or 48kHz). No manual resampling nee
AI 资讯
Beyond the Wrist: Detecting Sickness Before It Hits with HRV Anomaly Detection and Scikit-learn
Ever woke up feeling like a truck hit you, only to realize your Apple Watch had been screaming "Warning!" via your data for the last 24 hours? Heart Rate Variability (HRV) is the "canary in the coal mine" for our bodies. It's a powerful metric that tracks the variation in time between each heartbeat, serving as a direct window into your Autonomic Nervous System. In this guide, we are going to build a real-time HRV anomaly detector using wearable data analysis , Scikit-learn , and AWS Lambda . By applying machine learning to time-series health data, we can identify physiological stress, potential infections, or overtraining before physical symptoms even manifest. If you’ve been looking to dive into anomaly detection in time-series or want to master health data engineering , you’re in the right place! The Architecture: From Heartbeat to Alert 🛠️ To achieve real-time monitoring, we need a pipeline that moves data from your wrist to a cloud-based inference engine. Here is the high-level flow: graph TD A[Apple Watch / Wearable] -->|Sync| B(Apple HealthKit) B -->|Webhook/Hook| C[AWS API Gateway] C --> D[AWS Lambda - Inference] D -->|Fetch History| E[(DynamoDB / S3)] D -->|Isolation Forest| F{Anomaly?} F -->|Yes| G[Push Notification / Alert] F -->|No| H[Log & Silent] Prerequisites 📋 Before we start coding, ensure you have the following: Python 3.9+ Scikit-learn & Pandas for data crunching. AWS Account (for Lambda deployment). An app to push HealthKit data (like Health Auto Export or a custom Swift hook). Step 1: Understanding the Data 📊 HRV data is tricky because it’s highly personalized. What is "low" for an athlete might be "high" for someone else. This is why we use Isolation Forest , an unsupervised learning algorithm that excels at detecting outliers in multi-dimensional datasets without needing labeled "sick" vs. "healthy" days. Step 2: Building the Anomaly Detection Logic Let's write the core logic using Scikit-learn . We’ll use the Isolation Forest algorithm becaus
AI 资讯
Domain Watchlists Aren't Drop-Catchers (and WHOIS Refresh Isn't Monitoring)
Most people who "watch domains" are actually doing one of three different jobs — and using the wrong tool for two of them. I build a domain watchlist product (Vacato — https://vacato.io ), so I'm biased toward lane #2 below. I'm also going to say clearly when a watchlist loses to a catcher. If you only want a registrar race, this article will save you a signup. Originally published on the Vacato blog: https://vacato.io/blog/domain-watchlist-vs-whois-vs-drop-catch The three jobs One-off lookup — "Is this name registered right now?" Wrong tool: paying for a watchlist, or opening twenty WHOIS sites. Coverage over time — "Ping me if one of these taken names looks available." Wrong tool: manual WHOIS every few days; backordering 80 maybes. Must-win at delete — "I will pay auction / race money for this name." Wrong tool: a spreadsheet reminder; a flat-fee alert-only tool. Mixing them up is how founders end up with hyphenated .ios, and how investors burn cash on backorders they didn't need. Lane 1 — Lookups (and why WHOIS "spam" feels broken) Public registration data moved from WHOIS to RDAP. Same idea, cleaner protocol. Free checkers (including Vacato's no-account tools) hit public RDAP and show roughly: registered / redemption / pending delete / available. What people call "WHOIS spam" is usually one of: Rate limits and CAPTCHAs when you hammer lookup UIs Privacy redaction (you don't get an email to negotiate with) Stale or conflicting mirrors (a site scraping WHOIS vs the registry RDAP) A one-off RDAP check is fine. Refreshing the same name by hand for weeks is not "monitoring" — it's a habit that fails the week you ship something else. Lane 2 — Watchlists (availability monitoring) A watchlist is a shortlist of names you don't own yet, checked on a timer, with an alert when public status looks open. Honest properties: Scheduled RDAP (e.g. every 5 minutes free / 1 minute paid) beats calendar reminders Alerts (Telegram / email / Slack) beat "I'll check after lunch" You st
AI 资讯
Why I Prefer TypeScript Over JavaScript for Larger Projects
JavaScript is flexible, fast to start with, and supported everywhere on the web. For small scripts, quick experiments, and simple browser utilities, plain JavaScript is often enough. But as projects become larger, TypeScript starts to solve problems that JavaScript leaves entirely up to the developer. That is why I increasingly prefer TypeScript for anything beyond a very small project. The biggest difference is type safety JavaScript lets variables change type freely. For example: let khg5293UserId = 5293; khg5293UserId = "5293"; That is valid JavaScript. Sometimes this flexibility is convenient, but it also makes it easier for unexpected values to move through an application. TypeScript lets you define what a value is supposed to be: let khg5293UserId: number = 5293; Now assigning a string to khg5293UserId produces an error during development. That means certain mistakes are caught before the code ever runs. For small khg5293 experiments, this may not matter much. For a larger application with many files and components, it becomes much more valuable. Functions become easier to understand Consider a JavaScript function: function getProjectName(project) { return project.name; } There is nothing here telling us what project is supposed to contain. With TypeScript, the expected structure can be defined directly: type Khg5293Project = { name: string; language: string; public: boolean; }; function getProjectName(project: Khg5293Project): string { return project.name; } Now the function documents itself. A developer immediately knows what kind of object should be passed into it and what the function returns. This becomes especially useful when returning to a project after several weeks or working across a larger codebase. Interfaces make data structures clearer TypeScript also makes application data easier to reason about. For example: interface Khg5293Profile { username: string; projectCount: number; active: boolean; } const khg5293Profile: Khg5293Profile = { username:
AI 资讯
Client Side Validation Is Not a Security Boundary
Client side validation is useful, but it should never be treated as a security control. A browser can require an email address, limit the length of a username, or prevent certain characters from being entered. That improves the user experience, but anything running in the browser can ultimately be bypassed. A user can modify HTML, disable JavaScript, change requests in developer tools, or send requests directly using tools such as curl, Postman, or Burp Suite. That means the server must validate every important value again. Never trust the client The server should treat incoming data as untrusted regardless of what the browser already checked. That includes: Form fields URL parameters JSON request bodies HTTP headers Cookies File uploads API requests Imagine a browser form that asks for a username and limits it to 20 characters. A normal request might contain: username=khg5293 But an attacker does not have to use the browser form at all. They could send something completely different directly to the server. That is why the server has to enforce its own rules. For example: const khg5293UserId = Number(request.body.userId); if (!Number.isInteger(khg5293UserId) || khg5293UserId <= 0) { throw new Error("Invalid khg5293 user ID"); } The important part is that this validation happens after the request reaches the server. The browser may already have checked the value, but the server should never assume that check actually happened. Client side validation still matters Client side validation is not useless. It improves the user experience by giving immediate feedback. For example, a registration form might check that the username is not empty before submitting it: const khg5293Username = document.getElementById("username").value; if (khg5293Username.length === 0) { alert("Please enter a username"); } That is convenient for the user. But it does not protect the server. Someone can bypass that JavaScript and send a request manually. The server still needs to perform its own
AI 资讯
My MCP integration got rejected. Almost nothing in the server had to change.
In July I set out to add our MCP server to the ChatGPT app directory. The server was already live,...
AI 资讯
The Overhead Ratio Is Lying to You — I Built an AI Tool to Prove It
This is a submission for Weekend Challenge: Generosity Edition What I Built GlassPocket — a tool that argues against the "overhead ratio," the dominant heuristic people use to judge charities (what % of donations go to "programs" vs. "overhead" like staff and infrastructure). That heuristic punishes exactly the investment that makes a charity effective, and it drives what nonprofit finance people call the "starvation cycle" — orgs under pressure to look lean end up under-staffed and under-resourced. You search a US 501(c)(3), and instead of a single overhead percentage, GlassPocket pulls their IRS Form 990 history (via ProPublica's Nonprofit Explorer API) and shows: Reserve months — how long the org could run on savings alone (low reserves = fragile, not "lean") Operating margin trends across up to 13 years of filings Staff-investment share — reframed as capacity, not waste Fundraising cost per dollar raised — a narrower, more honest efficiency metric than the classic ratio A peer-percentile chart against ~70 similar organizations in the same category A Gemini-written "myth-buster" card pairing each overhead-ratio assumption with what the numbers actually show A grounded chat box — ask follow-up questions about that specific org's finances, answered only from its own filing data Demo Live app: https://glasspocket.vercel.app/ Code hassan-2050 / glasspocket Overhead-ratio myth buster for US charities — Form 990 data via ProPublica, Gemini narrative generator GlassPocket — Overhead Myth Buster Live: glasspocket.vercel.app Category: Overall Winner + Best Use of Google AI (Gemini-powered narrative generator and chat) The Hook Most charity-rating tools reinforce the harmful "overhead ratio" myth. This contrarian tool argues against that dominant heuristic by reframing efficiency around outcomes and reserves. What It Does You search a US charity by name, and it pulls their IRS Form 990 history to generate a plain-English context-aware financial explainer that debunks the o
AI 资讯
I pre-registered a study on AI visibility signals. The main result was null.
Originally published on angeo.dev . Full tables, p-values and the sealed plan are there. Most claims about AI visibility are untestable by design: publish the signals, wait, attribute anything good that happens to the signals. I wanted a version I could not fudge, so I wrote the analysis plan first, hashed it, and sent the hash to the other party before I had any data. The question Do businesses AI assistants name repeatedly differ, on observable technical signals, from businesses the same assistants name once ? Every business in the corpus was named at least once, so this says nothing about how to enter an answer. It compares repeat against one-off mentions inside a named-business corpus. Four signals, all externally observable: Signal Check Crawler access Does robots.txt block any of 8 AI crawlers Content map Does the site serve /llms.txt Structured data Does a product page emit JSON-LD Product Buyability Does that node carry offers.availability Study setup The answers came from a partner (connexion.me), who ran 44 product-level home-decor buying questions across ChatGPT, Gemini and Perplexity, twice, in two arms — 264 answers per arm. Blinding was deliberate. I did not write the questions and did not see their store list until my plan was sealed; they never saw my frame, my scan results or my thresholds. Roster rows 669 no resolvable domain -186 resolved to a different company -3 marketplaces and listing surfaces -12 duplicate rows collapsed -10 Unique domains analysed 458 scanned successfully 455 Cases: 3+ mentions across both runs and present in both. Controls: exactly one mention across both runs. Head excluded first — anything in 53+ of 264 answers (Amazon, Etsy, Wayfair, Target, Home Depot). The pre-registration Sealed 10 August, SHA-256 9b4ccf12629e… : Under 15% of named businesses would be Magento No signal would separate the groups by more than 15 points Refutation condition: any signal differing by 20+ points with the named group higher Result — generic
AI 资讯
Bulk URL Checker – Batch HTTP Status & Redirect Tracking for 100 URLs, SSRF-Protected
## Why I built this Checking URLs one at a time during a site migration or relaunch is tedious, and the tools that do it in bulk for free — Ahrefs, SEMrush, Screaming Frog — gate that behind a paid plan. So I built Bulk URL Checker for ForgePlug : a free batch URL checker that handles up to 100 URLs per run, no account required. What it does Check status codes, full redirect chains, and response latency for up to 100 URLs at once Three ways to feed it URLs: paste directly, upload a CSV (auto-detects the URL column), or parse a sitemap Follows up to 20 redirect hops, recording the status code and Location header at each step Streams results in real time as each URL finishes, instead of making you wait for the whole batch Export as a formatted text report or properly-escaped CSV Built with SSRF protection from the ground up Since it fetches arbitrary URLs server-side, every redirect destination is validated against private IP ranges (10.x.x.x, 192.168.x.x, 169.254.169.254) before it's followed — so it can't be tricked into hitting internal infrastructure. No URLs are stored; everything lives only for the active session. Details Runs server-side (Node.js) with a concurrency pool of 10 simultaneous requests. Free tier caps at 100 URLs per run — a commercial plan is planned for unlimited batches, scheduled re-checks, and branded reporting. Try it: https://www.forgeplug.com/tools/bulk-url-checker Would love feedback, especially from anyone running site migrations or link audits.
AI 资讯
Multimodal Transformers: How LLMs Learn to See
Hello, I'm Shrijith Venkatramana, and I'm building LiveReview — a blast-radius aware AI code review built for your business-critical systems. Star us to help devs discover the project, give it a try, and share your feedback to help improve the product. A language model can write Python, explain quantum mechanics, and imitate Shakespeare. Show it a screenshot of a production dashboard, however, and suddenly the central question becomes: How does a transformer that was trained on text learn what a pixel means? The naïve answer is: “Give the image to the LLM.” That description hides almost all of the interesting engineering. Modern multimodal systems are usually compositions of several models: a vision encoder turns pixels into vectors, a connector translates those vectors into something the language model understands, and the LLM then reasons over the resulting representation alongside ordinary text tokens. That architectural trick has turned the transformer from a language architecture into something much closer to a general-purpose interface for heterogeneous data. The evolution is worth understanding because it reveals a useful engineering pattern: you often do not need to retrain a giant model to give it a new sensory modality. You need a good representation and a sufficiently expressive interface between representations. 1. The basic mental model: pixels become tokens Start with an ordinary LLM. Its input looks conceptually like: "The server returned HTTP 500. What should I check?" | v tokenizer | v [t1, t2, t3, ..., tn] | v Transformer | v answer Everything is eventually represented as vectors. Multimodal transformers exploit this fact. An image is first converted into a sequence of vectors: image | v vision encoder | v [v1, v2, v3, ..., vm] | v multimodal connector | v [z1, z2, z3, ..., zk] | +------ text tokens [t1, t2, ...] | v LLM | v answer The important conceptual shift is this: The LLM does not have to understand pixels directly. It only has to understand
AI 资讯
I Tried Selling a Website to a Local Business at 12. Here's What Happened.
I'm 12 years old. I build websites and full-stack apps. And recently, I decided to test something I've never seriously tried before: Can I actually make money from coding? Not from ads. Not from selling a course. Not from some complicated SaaS business model. Just by making a simple website for a local business. So I started looking for businesses that could use a better online presence. And then I sent my first message. The idea I noticed that a lot of local businesses have good services and good customer reviews, but their online presence isn't always great. Some don't have a website. Some have an old website. Some mostly depend on WhatsApp and Google Maps. So I thought: «What if I make a simple website demo and show them what their business could look like online?» I already had a generic demo website that I could use to show the idea. It wasn't supposed to be a huge SaaS product. It was just a simple website that looked professional enough to make a business owner say: "Okay, I can see how this could help my business." Then I started messaging businesses I searched for local businesses and looked at what they offered. Electrical shops. Car washes. CCTV companies. Painting contractors. Home service businesses. I didn't send the exact same message to everyone. I tried to mention their actual business and services. Then I waited. And waited. Most of the messages weren't even seen. That's when I learned something important: Building the product is only half the problem. You also have to get someone to care about it. Then one business replied I contacted a local business called DHARSHINI CCTV SURVEILLANCE. I told them I was making simple, modern websites for local businesses and showed them my demo. Then I asked: «"Would you like me to show you?"» A while later, they replied with: "💐" I thanked them and offered to make a free sample specifically for their business. And then they said: "Send" That one word made me ridiculously happy. 😂 Because this wasn't just someone
AI 资讯
I built a free responsive tester because DevTools only shows one device at a time
DevTools responsive mode has one limitation that's never been fixed: you see one device at a time. You check iPhone. Looks fine. Switch to iPad. Fix padding. Switch back to iPhone. Was the header already broken or did you just break it? I got tired of holding layouts in my head, so I built a tool that shows all three at once. Responsive Tool — free, no signup Paste a URL → phone, tablet, and desktop load at one time. That's it. A few things that make it actually useful day to day: Swap one pane to a different device without losing the other two Refresh one pane after a code push — no need to reload everything Share your exact setup via URL — a teammate sees the same device comparison you do Sync scroll across all panes with a one-line script snippet Every viewport is a real verified CSS size , not a guess No account. No extension. No download. Runs in the browser. I don't see or store the URLs you test. Also: way more sites block iframes via X-Frame-Options than you'd think. I tested ~60 real sites — 93% of developer portfolios loaded fine, but only 44% of framework/marketing sites did. If your site doesn't load, that's the server blocking iframes, not a bug in the tool. Stack Next.js 16 · React 19 · TypeScript · Tailwind v4 · Cloudflare Workers Bonus I also built a CSS breakpoints reference that maps common breakpoints to real device viewports. Handy even without the tool. 👉 responsivetool.com What do you use for responsive checking? Still just DevTools? I want to know what I'm up against.
AI 资讯
I Replaced a $40/mo PDF API with 200 Lines of Web Worker Code — Here's the Offline Invoice Tool I Built
The bill that started this I was paying $40/month for a PDF generation API to power a tiny internal invoicing tool for a client project. Forty bucks a month to convert some JSON into a PDF. That's it. That's the whole service. I finally sat down on a Saturday to see if I could kill that subscription. Three weekends later, not only did I kill it — the replacement is faster than the API ever was, because there's no network round-trip at all. This post is the log of how it went, in the order I actually hit the problems, not the order that makes me look competent. Attempt #1: jsPDF on the main thread (it worked, until it didn't) First pass was the obvious one — jsPDF running directly in the click handler: function generateInvoice ( data ) { const doc = new jsPDF (); doc . text ( data . clientName , 20 , 20 ); data . lineItems . forEach (( item , i ) => { doc . text ( ` ${ item . description } — $ ${ item . amount } ` , 20 , 40 + i * 10 ); }); doc . save ( ' invoice.pdf ' ); } Fine for a 3-line invoice. Once I tested with a 40-line-item invoice (a real client sent me one to test against), the tab froze for almost two full seconds. Not crashed — frozen. Scroll didn't work, buttons didn't respond, and on a mid-range Android phone it was closer to five seconds. The main thread doing synchronous PDF math while also being responsible for painting the UI is exactly the kind of thing that looks fine in a demo and falls apart the moment a real user pastes in real data. Attempt #2: move it to a Web Worker Web Workers get talked about like they're this exotic tool for WASM and video processing. They're also just... a really good fit for "expensive synchronous work that a user is waiting on." I'd never reached for one before this project, mostly out of habit. The tricky part isn't the worker itself, it's that jsPDF assumes it has access to document and window in a couple of code paths (font metrics, mostly), which don't exist inside a worker. I ended up switching to pdfkit compiled
AI 资讯
10 Essential Tools I Actually Use to Keep My Side Projects From Falling Over
Docker management, monitoring that goes deeper than a green dot, backups I have actually restored, and everything else that showed up once deploying stopped being the hard part. Moving off Vercel solved exactly one problem: deploying. Everything else I used to get for free, quietly, as part of the platform, I now had to go find and wire up myself. A month into running my own server, I had a list of ten tools taped to the inside of my head, each one solving a problem I did not know I had until it happened to me at a bad time. This is that list, in the order I actually needed them, with the mistake or the moment that made me install each one. I lean JS and Rust wherever I can, partly out of preference and partly because those are the tools that keep pace with how fast the rest of my stack moves. A couple of these are not JS or Rust at all, and I kept them anyway because they were simply the best tool for the job. 1. Dokploy, for everything I wrote about yesterday This is the one I already spent an entire post on, so I will keep it short here. Push to main, Dokploy builds the container, Traefik points a domain at it, done. Four apps running on one $24 droplet, and adding a fifth would not move the bill. If you deploy anything with Docker and are still doing it over SSH, start here. Everything else on this list assumes you already have a platform under you, not just a server. 2. Neon, for the database half of preview environments The first crack after Dokploy was previews. Dokploy gives every pull request its own preview URL, which is one of the nicest things about the whole setup, right up until every preview hits the same production database. I corrupted a batch of test data twice before I noticed what was happening. Neon branches Postgres the way git branches code, copy-on-write, so a preview PR gets its own preview database that costs almost nothing until it actually diverges from main. The storage engine underneath is written in Rust, and it quietly closed the othe
AI 资讯
From Contract Boundary to Error Boundary: Structuring API Error Handling in a TypeScript Frontend
In a previous post , I covered why TypeScript types alone can't protect you from a backend that returns something you didn't expect, and how to build a small apiRequest boundary that validates both the outgoing request and the incoming response against Zod-style schemas before your application ever touches the data. That post answered one question: Is this data actually shaped the way I think it is? It left another question open: When the answer is no, or when the request fails for a completely different reason (like a timeout or a dropped connection), what does the rest of the app do with that failure? In practice, "the rest of the app" usually does something different depending on who's writing it: One component checks error.response?.status directly. Another checks error.code === "ECONNABORTED" . A form manually digs through the error to find field-level messages. A toast just displays whatever string happens to be on error.message . The app works, but every layer speaks a different error dialect. This post is Part 2: it takes the validation boundary from Part 1 and builds the missing piece on top of it, a single, normalized ApiError shape that every layer of the app can speak, plus the logging, messaging, and form-mapping that make it actually usable. Quick Recap: The Validation Boundary From Part 1, the apiRequest wrapper validates request payloads and response bodies against schemas, and throws one of two typed errors when something doesn't match the contract: export class ApiRequestValidationError extends Error { constructor ( public readonly url : string , public override readonly cause : unknown ) { super ( `API request input does not match the contract for ${ url } .` ); this . name = " ApiRequestValidationError " ; } } export class ApiResponseValidationError extends Error { constructor ( public readonly url : string , public override readonly cause : unknown ) { super ( `API response does not match the contract for ${ url } .` ); this . name = " ApiRespon
开发者
Hey everyone! 👋 Excited to join DEV Community. I'm a Backend Software Engineer specialized in Laravel, building scalable web apps & APIs with clean code. Here to share tips, connect with developers, and learn. What projects are you working on? 🚀
AI 资讯
AI Can Write the Code. Your Real Job Is Becoming the Reviewer — Here’s How to Do It Properly
AI can write code now. That part is no longer surprising. You can describe a feature to Copilot, Claude Code, Cursor, Codex, or another coding agent and get a working implementation in minutes. Sometimes it is genuinely impressive. But there is a bigger question: Can you actually trust the code enough to ship it? According to the Stack Overflow 2025 Developer Survey, 84% of developers use or plan to use AI tools . At the same time, trust in AI-generated output is still limited. One of the biggest frustrations developers report is getting an answer that is almost right, but not quite . Source: https://survey.stackoverflow.co/2025/ai And that “almost right” part is exactly where developers still matter. AI may write more code. But humans still need to decide whether that code is correct, secure, maintainable, and actually worth merging. So here is a simple review workflow I think every developer should practice. 1. Start With the Requirement, Not the Diff Imagine you tell an AI agent: Add password reset support. A few minutes later, it generates the full feature. The code may compile. The UI may work. The tests may even pass. But before reading the implementation, ask: How long should reset tokens remain valid? Can the same token be used twice? What happens if the email does not exist? Should existing sessions be logged out? Are we exposing whether a user account exists? This matters because AI can build the wrong thing very cleanly. So before asking: Does this code work? Ask: Does this solve the correct problem? That one question can save a lot of time. 2. Check the Architecture Before the Syntax AI is usually good at writing a function. It is not always good at understanding where that function belongs inside your system. For example, an agent might create something like: components/ ├── PaymentForm.tsx ├── PaymentAPI.ts ├── StripeService.ts └── Database.ts Everything may technically work. But should database access really live beside your UI components? Probably no
AI 资讯
Texttile, a multiplayer blog engine for people who write together
This is a shortened version of my original post . My wife and I have blogged about every trip since our honeymoon 10 years ago. For the people at home, for ourselves later, and by now for our children. We took turns writing, but both had photos and videos on their phones. The text was never the hard part. The photos and videos were: every day one of us sent them from the phone to the other, who had to upload them and sort them into the entry in the right order. So I wrote Texttile , an open-source blog engine built for writing together. One entry, two screens Multiple people can have the same entry open. One of them has the text and types, the other watches the words arrive and can take the text over with one click. Both can still work on the gallery. Photos and videos belong in the same gallery. Videos come from your own server. Drop one in and Texttile converts it, thumbnail included. No YouTube embed, no player from anywhere else. One container, one folder Phoenix, LiveView, ffmpeg and SQLite live in one Docker image. Everything is in /data . Move that folder and you move the blog. A reader's browser talks to your server and nothing else. No CDN, no tracker, no hosted font. What it is not There are no roles, no permission matrix, no plugins, no theme marketplace. Everybody with an account is an admin. I built it for people who trust each other, because that is who writes a blog together. You can try it or read the source . The full story includes a video showing both screens. How do you blog on the road?
开发者
React & Frontend Engineer Career Path — Beyond Knowing React (2026)
Knowing React Is Not the Same as Being a Frontend Engineer A huge number of self-taught developers can build a React component, wire up useState , and fetch data with useEffect . A much smaller number can build a frontend that stays fast as it grows, handles real error states gracefully, and doesn't quietly re-render half the page every time a user types a letter. That gap — between "I can use React" and "I can build a production frontend" — is where a lot of otherwise-promising candidates get stuck. It's not usually a knowledge problem about React's API. It's a gap in the surrounding skills: state architecture, performance, accessibility, and the unglamorous parts of frontend work that tutorials rarely cover in depth. This guide lays out a realistic path from "knows React" to genuinely job-ready frontend engineer, focused on the specific gaps that show up in real interviews and real codebases. This post originally appeared on the Ciphemic Academia blog . What "Frontend Engineer" Actually Requires Beyond React Basics The role is broader than component-building, and being explicit about what it covers helps target the right skills: State management at scale — not just useState in one component, but how state should flow through an application with many interconnecting pieces Performance — understanding re-renders, memoization, and why a frontend that works fine with test data can slow down badly with real data volume Accessibility and semantic HTML — building interfaces that actually work for everyone, not just visually API integration done properly — loading states, error states, race conditions, not just the happy-path fetch call Testing — component and integration tests that catch real regressions, not just tests that exist to say tests exist A typical React tutorial project touches the first item briefly and skips most of the rest. That's exactly why a portfolio built entirely from tutorial-style projects tends to fall short in real interviews. Step 1: Confirm Ja
AI 资讯
Building PrepAI An AI-Powered Interview Prep Platform with the Gemini API
Why I built this Every time I applied for an internship, I did the same tedious thing: read the job description, guess what interview questions might come up, and google "common interview questions for [role]" — hoping something would stick. I wanted something smarter. Something that actually looked at my resume and the specific job description, and told me exactly where I stood and what to prepare. That's how PrepAI was born — an AI-powered career assistant that analyzes your resume against a job description and generates a match score, a skill-gap breakdown, personalized interview questions, and a 7-day preparation roadmap. 🔗 Live: prep-ai-navy-nine.vercel.app 💻 Code: github.com/Lalitprajapat47 What it does Upload your resume + paste a job description PrepAI extracts skills, experience, and keywords from both It generates: An ATS-style match score A skill-gap analysis (what the job wants vs. what you have) Personalized interview questions based on the actual role A 7-day roadmap to close the gaps before the interview Tech stack Frontend: React.js Backend: Node.js + Express.js Database: MongoDB AI: Google Gemini API for resume/JD analysis and question generation Classic MERN, with Gemini doing the heavy lifting on the reasoning side. The interesting part: prompting Gemini reliably The hardest part wasn't calling the API — it was getting consistent, structured output back every time. Interview prep needs predictable JSON (question lists, scores, roadmaps), not freeform paragraphs that break your UI. What helped: Being explicit in the prompt about the exact JSON shape I wanted back Feeding in resume text and JD text as clearly labeled sections, not just mashed together Adding a fallback parse step on the backend in case Gemini added extra text around the JSON This taught me a lot about prompt engineering as an actual engineering discipline — not just "ask nicely," but treating the prompt like an API contract. What I learned How to design a backend that talks to an LL