AI 资讯
How I Built a Browser-Based File Compression Tool for India Using Canvas API and pdf-lib — No Backend Needed
I built ResizeKB — a free image and PDF resizer built specifically for Indian users. 25+ tools. Zero server uploads. Pure HTML, CSS, JavaScript. Here's how and why. The Problem Every Indian applying for government jobs, exams, or bank accounts hits the same wall — portals with strict KB limits rejecting documents. UPSC wants photo under 300KB. SSC wants under 50KB. Banks need Aadhaar PDF under 500KB. Every portal is different. Every rejection wastes someone's time and opportunity. Most people have no idea how to resize to an exact KB. They either give up or use random tools that upload their Aadhaar and PAN card to unknown servers. I built a tool that solves this in one click — with zero server upload. The Tech Stack No framework. No backend. No database. Canvas API for image processing pdf-lib for PDF compression Vanilla JavaScript only Cloudflare Pages for hosting — free, global CDN, auto deploys from GitHub Total infrastructure cost: ₹1,162 per year for the domain. Everything else free. Image Compression — The Binary Search Algorithm The core challenge is compressing to an exact KB target without over-compressing. Most tools use a fixed quality setting like 60% which destroys image quality. The right approach is binary search on JPEG quality: javascriptasync function compressToTargetSize(file, targetKB) { const targetBytes = targetKB * 1024; let low = 0.1; let high = 1.0; let result = null; const img = await loadImage(file); const canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); while (high - low > 0.01) { const mid = (low + high) / 2; const blob = await canvasToBlob(canvas, 'image/jpeg', mid); if (blob.size <= targetBytes) { result = blob; low = mid; } else { high = mid; } } return result; } This finds the highest quality setting that still hits your target KB. Result is the sharpest possible image at that file size — never over-compressed. PDF Compress
AI 资讯
Why I stopped pasting into online Fake Data Generator tools
Every online Fake Data Generator tool I used had the same quiet flaw: whatever you paste gets POSTed to someone's server. For a Fake Data Generator, that paste is often exactly the sensitive thing — a token, a config, an API response. So I built Fake Data Generator to not do that. Generate fake names, emails, UUIDs, addresses — custom columns, CSV/JSON export. 100% browser-side — and it runs entirely in your browser, so there's nothing to send and nothing to breach. You don't have to take my word for it: open DevTools → Network, use the tool, and watch the tab stay empty. One HTML file, View-Source-able. https://faker.platotools.com/ It's part of platotools.com — a set of single-purpose, client-side dev tools. Feedback and edge-case bug reports very welcome.
AI 资讯
Fix: babel-plugin-transform-flow-strip-types broken in Babel 7 and 8
The original babel-plugin-transform-flow-strip-types hasn't been updated in 9 years and breaks silently in Babel 7 and 8 environments. The fix I published a maintained fork that works as a drop-in replacement: npm install --save-dev babel-plugin-transform-flow-strip-types-maintained Then update your .babelrc: { "plugins": ["transform-flow-strip-types-maintained"] } That's it. No other changes needed. What's fixed Babel 7 and 8 peer dependency conflicts Missing syntax plugin declaration Deprecated visitor patterns allowDeclareFields support Automated migration If you want to update your entire project automatically: npx flow-strip-migrate . This updates your package.json and babel config in one command. More info: https://flowstrip.netlify.app npm: https://www.npmjs.com/package/babel-plugin-transform-flow-strip-types-maintained
开源项目
🔥 chinese-poetry / chinese-poetry - The most comprehensive database of Chinese poetry 🧶最全中华古诗词数据
GitHub热门项目 | The most comprehensive database of Chinese poetry 🧶最全中华古诗词数据库, 唐宋两朝近一万四千古诗人, 接近5.5万首唐诗加26万宋诗. 两宋时期1564位词人,21050首词。 | Stars: 51,677 | 95 stars today | 语言: JavaScript
开源项目
🔥 Acode-Foundation / Acode - Acode - powerful text/code editor for android
GitHub热门项目 | Acode - powerful text/code editor for android | Stars: 5,511 | 20 stars today | 语言: JavaScript
开源项目
🔥 sveltejs / kit - web development, streamlined
GitHub热门项目 | web development, streamlined | Stars: 20,556 | 4 stars today | 语言: JavaScript
开源项目
🔥 NomaDamas / k-skill - 한국인을 위한 스킬 모음집 - SRT, KTX, 카카오톡, 한글과컴퓨터, 날씨, 미세먼지, 법령, 주식정보,
GitHub热门项目 | 한국인을 위한 스킬 모음집 - SRT, KTX, 카카오톡, 한글과컴퓨터, 날씨, 미세먼지, 법령, 주식정보, 조선왕조실록, KBO, K-리그, LCK, 특허 검색, 토스 증권, 맞춤법 검사, 중고차 가격, 쿠팡, 네이버 블로그, 다이소, 올리브영, 택배 송장 조회 등등... | Stars: 5,411 | 19 stars today | 语言: JavaScript
开源项目
🔥 datawhalechina / easy-vibe - 💻 vibe coding 2026 | Your first modern Coding course beginne
GitHub热门项目 | 💻 vibe coding 2026 | Your first modern Coding course beginners to master step by step. | Stars: 16,458 | 151 stars today | 语言: JavaScript
AI 资讯
Building a Privacy-First Media Converter in the Browser: No Servers, No Cloud, 100% Client-Side (RAM-Friendly)
Most online file converters require uploading your documents, images, or videos to an unknown server. This is slow, inconvenient, and raises serious privacy concerns. I decided to build something different: a converter that works entirely inside your browser. Processing large files without a backend presents two main engineering challenges: How do you avoid consuming all available RAM? How do you prevent the user interface from freezing? This article explains how I solved these problems using OPFS, Web Workers, and a Backpressure mechanism. The result is a working tool you can try right now: PixelForge Free . The Architecture at a Glance Here is the simplified data flow of the entire pipeline: Drag & Drop → OPFS (Virtual Disk) → Worker Pool (Backpressure) → ZIP Stream → Download Problem 1: Out-of-Memory (OOM) Crashes The Challenge: Loading many files directly into the browser's memory is impossible. A user dropping a folder with 100+ high-resolution images would instantly crash the tab. The Solution: Origin Private File System (OPFS) OPFS provides a fast, isolated virtual disk inside the browser. Instead of loading files into RAM, my pipeline intercepts the drop event and streams the raw binary data directly to this virtual disk. Here is a simplified version of how it works: // Get a reference to the virtual disk const root = await navigator . storage . getDirectory (); const fileHandle = await root . getFileHandle ( `input_ ${ id } .raw` , { create : true }); // Create a writable stream to the disk const writable = await fileHandle . createWritable (); // Stream the file directly from the user's computer to the virtual disk await file . stream (). pipeTo ( writable ); This allows the application to accept a folder with 500+ items without consuming more than a few megabytes of actual RAM. The data stays on the user's SSD, not in memory. Problem 2: UI Freezing The Challenge: Image compression, PDF parsing, and video encoding are CPU-intensive operations. Running them
AI 资讯
async/await is a Generator in Disguise. Let's Build It From Scratch
You write await a dozen times before lunch. Fetch a row, await it. Call a service, await that. It works, you move on, and you never have to think about what the word is doing. Then one day someone asks you to explain it. Maybe it's an interviewer."But what does await actually do?" And you open your mouth and what comes out is "it, uh, waits for the promise." Which is true, and also explains nothing. We can build async/awit mechanism from scratch using generators as a learning exercise. It requires a pause button wired to a small loop that waits on a promise and then presses play again. You already know one half of that machinery if you read the last post in this series . The other half is a trick generators have that we glossed over. Put the two together and you can build a working version of async/await yourself, by hand, and watch it behave exactly like the real thing. Let's do that. The shape of the problem Strip await down to what it has to accomplish and you get two requirements: First, a function has to be able to stop in the middle. Right at the await, freeze everything, the local variables, the spot in the loop, all of it, and hand control back to whoever called it. Normal functions can't do this. They run start to finish and that's the deal. Second, something on the outside has to wait for the promise to settle and then nudge the frozen function back to life, handing it the resolved value as if the await expression had simply evaluated to it. That's the whole job. A function that pauses, and a driver that resumes it when a promise is ready. Hold that picture, because the rest of this is just filling in those two pieces with things JavaScript already gives you. The half you've seen: pausing A generator function, the function* kind, can pause itself with yield and resume later from the exact same spot. We leaned on that hard in the CSV piece to pull rows through a pipeline one at a time. A line came in, got yielded, and the generator sat frozen until someone
AI 资讯
From Monolith to Microservices: Why I Redesigned Finovara's Architecture - Finovara
At some point, a monolith starts working against you. In my case, Finovara was a single Spring Boot application handling everything (authentication, transactions, limits, piggy banks, notifications, activity logs, currency conversion) The bigger it got, the harder it was to change anything without worrying about something else breaking. So I broke it apart. This post is about the first three pieces I extracted: the API Gateway , the activity-log-backend , and a shared module called contracts-backend . The Old Structure Everything lived in one Spring Boot app. The activity log — which tracks everything a user does in the app (expenses added, limits changed, logins, account changes) — was tangled up with the core business logic. Adding a new type of activity meant touching the same codebase responsible for transactions, security, and everything else. The New Structure finovara-backend/ ├── api-gateway/ ├── activity-log-backend/ ├── contracts-backend/ └── core-backend/ Four modules (there will be more). Each with a clear responsibility. API Gateway The gateway is the single entry point for every request coming from the frontend. It runs on port 8888 with SSL enabled and uses Spring Cloud Gateway (WebFlux-based). Routing is simple and declarative: routes : - id : activity-log-backend uri : ${ACTIVITY_LOG_URL} predicates : - Path=/api/account-activity/**,/api/archive-activities/** - id : notification-backend uri : ${NOTIFICATION_BACKEND_URL} predicates : - Path=/api/notification-settings/** - id : core-backend uri : ${CORE_BACKEND_URL} predicates : - Path=/** Activity log routes go to activity-log-backend . Notification routes go to notification-backend . Everything else falls through to core-backend . The gateway also handles CORS centrally — https://localhost:5173 is the only allowed origin, with credentials support. No individual service needs to worry about CORS anymore. One thing worth noting: the gateway uses use-insecure-trust-manager: true for the HTTP client. Th
AI 资讯
From Monolith to Microservices: Why I Redesigned Finovara's Architecture - Finovara
At some point, a monolith starts working against you. In my case, Finovara was a single Spring Boot application handling everything (authentication, transactions, limits, piggy banks, notifications, activity logs, currency conversion) The bigger it got, the harder it was to change anything without worrying about something else breaking. So I broke it apart. This post is about the first three pieces I extracted: the API Gateway , the activity-log-backend , and a shared module called contracts-backend . The Old Structure Everything lived in one Spring Boot app. The activity log — which tracks everything a user does in the app (expenses added, limits changed, logins, account changes) — was tangled up with the core business logic. Adding a new type of activity meant touching the same codebase responsible for transactions, security, and everything else. The New Structure finovara-backend/ ├── api-gateway/ ├── activity-log-backend/ ├── contracts-backend/ └── core-backend/ Four modules (there will be more). Each with a clear responsibility. API Gateway The gateway is the single entry point for every request coming from the frontend. It runs on port 8888 with SSL enabled and uses Spring Cloud Gateway (WebFlux-based). Routing is simple and declarative: routes : - id : activity-log-backend uri : ${ACTIVITY_LOG_URL} predicates : - Path=/api/account-activity/**,/api/archive-activities/** - id : notification-backend uri : ${NOTIFICATION_BACKEND_URL} predicates : - Path=/api/notification-settings/** - id : core-backend uri : ${CORE_BACKEND_URL} predicates : - Path=/** Activity log routes go to activity-log-backend . Notification routes go to notification-backend . Everything else falls through to core-backend . The gateway also handles CORS centrally — https://localhost:5173 is the only allowed origin, with credentials support. No individual service needs to worry about CORS anymore. One thing worth noting: the gateway uses use-insecure-trust-manager: true for the HTTP client. Th
开发者
I built a free image converter that runs 100% in your browser — no upload, no signup
Hey DEV community! 👋 I built IMGVO — a free image tool that works entirely in your browser. What it does Convert JPG, PNG, WebP, AVIF, HEIC and more Compress images up to 90% without quality loss Crop, resize, rotate, watermark Works offline (PWA) Why I built it Most image tools upload your files to servers. I wanted something private and instant. Tech 100% vanilla JavaScript No backend, no server Works offline as PWA Privacy first No files uploaded to any server. Everything runs locally in your browser. 🆓 Free, no signup required. 👉 Try it: https://imgvo.com Would love your feedback! 🙏
开源项目
🔥 tiagozip / cap - Free, open-source and self-hosted CAPTCHA alternative to reC
GitHub热门项目 | Free, open-source and self-hosted CAPTCHA alternative to reCAPTCHA. Privacy-first and powered by proof-of-work and instrumentation challenges. | Stars: 6,767 | 59 stars today | 语言: JavaScript
开源项目
🔥 ritesh-1918 / HELPDESK.AI - A full-stack AI helpdesk platform that uses machine learning
GitHub热门项目 | A full-stack AI helpdesk platform that uses machine learning, NLP, and OCR to automatically analyze support requests, detect similar incidents, and help teams resolve technical issues faster. | Stars: 139 | 4 stars today | 语言: JavaScript
开源项目
🔥 Gracker / SmartPerfetto - use ai analysis Performance issue with perfetto
GitHub热门项目 | use ai analysis Performance issue with perfetto | Stars: 491 | 1 star today | 语言: JavaScript
开源项目
🔥 webpack / webpack - A bundler for javascript and friends. Packs many modules int
GitHub热门项目 | A bundler for javascript and friends. Packs many modules into a few bundled assets. Code Splitting allows for loading parts of the application on demand. Through "loaders", modules can be CommonJs, AMD, ES6 modules, CSS, Images, JSON, Coffeescript, LESS, ... and your custom stuff. | Stars: 65,757 | 2 stars today | 语言: JavaScript
AI 资讯
JavaScript Data Types Explained: Primitive vs Non-Primitive Data Types
JavaScript Data Types: Primitive and Non-Primitive Data Types Data types are an important concept in JavaScript because they define the kind of value a variable can store. Understanding data types helps developers write reliable and efficient code. What is a Data Type? A data type defines what kind of value a variable can hold. Example let name = " John " ; // String let age = 25 ; // Number let isActive = true ; // Boolean In the above example, each variable stores a different type of value. Types of Data Types in JavaScript JavaScript data types are broadly classified into two categories: Primitive Data Types Non-Primitive Data Types Primitive Data Types Primitive data types store a single and simple value. Characteristics Store a single value. Immutable (cannot be changed directly). Compared by value. Stored directly in memory. Types of Primitive Data Types 1. String Used to store textual data. let name = " John " ; 2. Number Used to store numeric values. let age = 25 ; let price = 99.99 ; 3. Boolean Represents either true or false . let isLoggedIn = true ; 4. Undefined A variable that has been declared but not assigned a value. let city ; console . log ( city ); // undefined 5. Null Represents the intentional absence of a value. let user = null ; 6. Symbol Used to create unique identifiers. let id = Symbol ( " id " ); 7. BigInt Used to store very large integers beyond the safe Number limit. let largeNumber = 123456789012345678901234567890 n ; Non-Primitive Data Types Non-primitive data types store multiple values or complex data structures. Characteristics Can store collections of data. Mutable (their contents can be modified). Compared by reference. Stored as references in memory. Types of Non-Primitive Data Types 1. Array Used to store multiple values in a single variable. let colors = [ " red " , " green " , " blue " ]; 2. Object Used to store data as key-value pairs. let person = { name : " John " , age : 25 }; 3. Function Functions are reusable blocks of co
AI 资讯
Cypress Testing: Complete Beginner's Guide
Section 1: Getting Started with Cypress 1. Installing and Setting Up Cypress Prerequisites Before installing Cypress, ensure you have Node.js installed on your machine. Cypress requires Node.js 18.x or 20.x and above. You should also have an existing React project or create a new one. Check your Node.js version by running this command in your terminal: node --version # Should output v18.x.x or higher Creating a React Project (Optional) If you don't have an existing React project, create one using Vite which is the recommended approach for new React projects: npm create vite@latest my-react-app -- --template react cd my-react-app npm install Installing Cypress Navigate to your React project directory and install Cypress as a development dependency. Cypress is a fairly large package, so the installation might take a minute or two: npm install cypress --save-dev # Or using yarn yarn add cypress --dev Opening Cypress for the First Time After installation, open Cypress for the first time. This will create the initial folder structure and configuration files: npx cypress open When Cypress opens for the first time, you'll see a welcome screen where you can choose between E2E Testing and Component Testing. Select E2E Testing to get started with end-to-end tests. Cypress will then prompt you to choose a browser. You can select Chrome, Firefox, Edge, or Electron. Choose your preferred browser and click Start E2E Testing in [Browser] . Adding NPM Scripts Add convenient scripts to your package.json for running Cypress tests: { "scripts" : { "dev" : "vite" , "build" : "vite build" , "cy:open" : "cypress open" , "cy:run" : "cypress run" , "test:e2e" : "start-server-and-test dev http://localhost:5173 cy:run" } } Tip: Use npm run cy:open for interactive development with the Cypress Test Runner. Use npm run cy:run for headless execution in CI/CD pipelines. 2. Understanding Cypress Project Structure Project Directory Overview After initializing Cypress, you'll notice several new fold
AI 资讯
I Built a Free Open-Source EU AI Act / NIST AI RMF / ISO 42001 Crosswalk Tool - Here Is What I Found
Every week I see the same question in AI governance communities: "We already have NIST AI RMF implemented. Does that cover our EU AI Act obligations?" The honest answer is: sometimes yes, sometimes partially, and sometimes not at all. The problem is that nobody had built a clean, free, interactive tool that showed exactly which controls map to which, how strong those mappings actually are, and where the genuine gaps are. So I built one. Live tool: suhanasayyad.github.io GitHub: SuhanaSayyad / eu-ai-act-crosswalk-tool Interactive crosswalk mapping EU AI Act obligations to NIST AI RMF and ISO 42001 controls, with mapping strength indicators, gap analysis, and source links. 30 controls mapped. Free and open source. EU AI Act × NIST AI RMF × ISO 42001 - Interactive Compliance Crosswalk Tool An open-source tool that maps EU AI Act obligations to their equivalents in NIST AI RMF and ISO 42001, with mapping strength indicators, gap analysis, and source document links. Built for compliance teams, AI governance practitioners, and anyone trying to understand how these three frameworks relate to each other. Live demo: https://suhanasayyad.github.io/eu-ai-act-crosswalk-tool Built by: Suhana Sayyad | MSc Cybersecurity, TUS Athlone Why I built this Every organisation dealing with the EU AI Act is being asked the same questions: "We already have NIST AI RMF controls in place. Does that cover our EU AI Act obligations?" "We're pursuing ISO 42001 certification. Does that satisfy the regulation?" The honest answer is: sometimes yes, sometimes partially, and sometimes not at all. The problem is that nobody had built a clean, free, interactive tool that showed exactly which… View on GitHub What the tool does The EU AI Act / NIST AI RMF / ISO 42001 Interactive Crosswalk Tool maps 30 EU AI Act obligations to their nearest equivalents in NIST AI RMF and ISO 42001. For each mapping it shows a strength rating - Strong, Partial, Indirect, or No Equivalent - so compliance teams know which map