AI 资讯
Where to Publish a Web Game in 2026
A finished browser game is a bundle of static files. Whether you built it in Phaser, Three.js, Babylon.js, Godot, or plain canvas code, the output uploads anywhere, which is exactly why the publishing decision trips people up. Every channel accepts the same build, so the choice is never technical. It is about who owns the audience, who owns the money, and who owns the URL. Here is how the three channels actually compare once you have shipped to all of them. The Three Channels Game portals aggregate thousands of titles, monetize with ads, and share revenue. Indie platforms like itch.io act as storefronts you control, with community feedback attached. Self-hosting on your own domain gives you everything except an audience. Most developers who do this well use more than one at the same time. The marginal cost of adding a channel is usually just reading the submission guidelines and wiring up an SDK, so treating them as either/or leaves reach on the table for no reason. What Portals Actually Require CrazyGames reaches over 20 million monthly players and runs a two stage process. Basic Launch takes your game with minimal integration and tests it with a limited audience for around two weeks. Hit their engagement benchmarks and you are invited to Full Launch, which needs the full SDK for ads, auth, cloud saves, and analytics. Their technical bar for Basic Launch is an initial download under 50 MB, fewer than 1,500 files, and PEGI 12 content. Poki is curated and editorially reviewed, leans mobile-responsive, and pulls strong search traffic with a younger audience. GameDistribution syndicates across hundreds of publisher sites through an embed widget, so you get reach but little brand visibility. Newgrounds still rewards experimental work with a community that engages rather than an SDK that monetizes. The trade in all four cases is the same: the portal brings the players, and in return it owns the player relationship and can change terms whenever it wants. Self-Hosting With
AI 资讯
Optimizing Large-Scale MongoDB Aggregation Pipelines for Performance
Originally published on tamiz.pro . MongoDB aggregation pipelines are powerful tools for processing and transforming data directly within the database. However, when dealing with large datasets, poorly optimized pipelines can become a significant performance bottleneck. This deep-dive explores advanced strategies and best practices to ensure your large-scale MongoDB aggregation pipelines run efficiently and effectively, transforming raw data into actionable insights without grinding your system to a halt. Table of Contents Understanding the Aggregation Pipeline Lifecycle The Critical Role of Indexing Indexes for $match and $sort Stages Compound Indexes and Covered Queries Partial Indexes for Specific Workloads Strategic Stage Ordering Pushing $match and $project Early Leveraging $sort and $limit Together Memory Management and Disk Spills allowDiskUse and its Implications Strategies to Minimize Disk Spills Leveraging the Query Optimizer and Explain Plan db.collection.explain() Interpreting Explain Plan Output Sharding Considerations for Aggregations Shard Key Design for Aggregation Workloads Targeted vs. Broadcast Aggregations Advanced Optimization Techniques Using $lookup for Joins and its Performance Impact Optimizing $group Stages Batching and Incremental Aggregations Production Best Practices Frequently Asked Questions Understanding the Aggregation Pipeline Lifecycle Before diving into optimizations, it's crucial to understand how MongoDB processes aggregation pipelines. An aggregation pipeline is a sequence of stages that process documents from a collection. Each stage performs an operation on the input documents and outputs a stream of documents to the next stage. This stream-based processing is key to its efficiency, but it also means that the output of one stage directly impacts the performance of subsequent stages. The MongoDB query optimizer attempts to reorder certain stages for efficiency, but it's not omniscient. Your strategic design choices profoundly
AI 资讯
🐍 Fixing a `google-genai` Version Mismatch and Verifying the Behavior with pytest [1/3]
Introduction Hello from Japan! 🇯🇵 I am tosane932 , a professional truck driver working in logistics while teaching myself Python. In my previous article, I tested a Docker multi-stage build and measured the actual change in image size. At the end of that article, I said that I would write next about pytest and CI/CD. This article was supposed to be the practical follow-up. However, while preparing for that work, I encountered an unexpected side issue. I only intended to introduce Flask-Migrate. Instead, the pip installation logs revealed that the version of a library in my local development environment had been changed without me noticing. The library was: google-genai From there, I went through the following process: Identify the version mismatch Restore the version that had already been tested locally Update requirements.txt Manually verify the Gemini API functionality Run pytest to check for regressions This article records that process without hiding the inconvenient parts. https://github.com/tosane932/sales_data_app Overview While installing Flask-Migrate, I noticed a mismatch between: The version of google-genai installed in my local development environment The version declared in requirements.txt The local environment had been using: google-genai 2.10.0 However, requirements.txt still specified: google-genai==2.4.0 When I ran: pip install -r requirements.txt pip followed the configuration file and replaced the newer local version with the older declared version. This article explains how I discovered the issue, synchronized the environments, and verified the application behavior with automated tests. 1. The Problem and Its Background I was preparing to introduce Flask-Migrate. During that work, I ran: pip install -r requirements.txt The installation log contained the following lines: Attempting uninstall: google-genai Found existing installation: google-genai 2.10.0 Uninstalling google-genai-2.10.0: That message caught my attention. After checking the environ
AI 资讯
The Shape of Failure: Before You Blame the AI
Every automated system receives a particular shape of the world. That shape is expressed through records, documents, events, exceptions, and missing values. If the designers have not identified those forms—and the ways they can become malformed—the machine inherits their ignorance and reproduces it at scale. The question is not simply whether the AI failed. The useful question is whether the human-built system knew what success meant, knew the shape of its data, and knew how to recognize when it was wrong. Start with the shape of the data Before selecting a model, draw the workflow as a sequence of data transformations. What enters each stage? In what form and from what source? Which values are valid, absent, duplicated, stale, delayed, or contradictory? How will each violation be detected? What must the workflow do next? Each data shape needs a corresponding failure model. An unknown here is not merely uncertainty for the machine; it is a measurement failure in the organization. The remedy is to collect the missing data or explicitly design for its absence. Otherwise, the system is being asked to operate in a world its designers have not described. Stabilize the deliverable A system cannot be stabilized around a target that continues to move. The deliverable must be more than an aspiration written in a prompt. It should be expressed as observable conditions and anchored to a representative corpus: examples that are acceptable; examples that are unacceptable; examples that are genuinely ambiguous. Human reviewers should first demonstrate that they can apply those distinctions consistently. If they cannot agree on what success looks like, the model is not being measured against a specification. It is being measured against human disagreement disguised as one. The model is not the system Only then does it become meaningful to place an AI model inside the workflow. The model is one transformation among many: Input → validation → retrieval → normalization → model infere
开发者
The Tech Market Situation is Crazy
submitted by /u/deepCelibateValue [link] [留言]
AI 资讯
🚀 TMA DevKit v2: Local Emulator for Telegram Mini Apps + MCP AI Debugging
😤 The Problem That Drives Everyone Crazy Ever tried building a Telegram Mini App? Write your code. Spin up ngrok (and pray it doesn't crash). Go to @BotFather, paste the tunnel URL. Grab your phone, open the bot, type console.log() — and pray again. Repeat for every theme, platform, and user type you need to test. It's 2015, folks. And there's still no official emulator. "The main difficulty is the inability to run a project as easily as in a browser via localhost — and the absence of a developer console." — Habr, March 2025 💡 Introducing: TMA DevKit A local emulator and bridge inspector for Telegram Mini Apps. Think Redux DevTools, but for window.Telegram.WebApp. In one sentence: paste your Mini App URL into the panel, and it runs inside an iframe with a full emulation of the Telegram client — no phone, no ngrok, no BotFather. ✨ What DevKit v2 Can Do (and Why It's Awesome) 🧠 MCP Server for AI-Powered Debugging — Brand New! Connect any AI assistant (Claude, GPT, local models) via the Model Context Protocol. Ask questions about your app's state, event flow, or initData validation — and get instant debugging suggestions. 🔧 A Real Mock, Not a Stub Full window.Telegram.WebApp API surface (all methods, properties, events). Cryptographically valid initData generation with HMAC-SHA-256 signature using your bot token. Backend validation passes as in production. Compatible with @telegram-apps/sdk v3 out of the box. ⚡ 5 One‑Click Quick Scenarios Scenario Description iOS Premium iPhone user with Premium subscription Android Free Regular Android user New User With referral parameter Group Launch Emulates opening from a group chat Desktop Wide viewport on computer Switch contexts in seconds — no manual input. 📊 Bridge Event Inspector All web_app_* calls displayed in real time. Group by type, filter, pause, export logs as .txt. emit console to fire client → app events (theme_changed, main_button_pressed, etc.). ☁️ CloudStorage Editor Visual key‑value editor. No more guessing what
AI 资讯
I built an AI job-search agent solo — here's the full stack
I spent the last couple of months building Reclaim — an AI job-search agent for engineers, done solo, taking up nights and weekends. It reads your résumé, scores it honestly, and matches you against real open roles. It's live at reclaim.careers (free scan, no signup). This isn't a launch post — it's a breakdown of the stack and, more usefully, the things that broke. Here's how it's built. The stack Frontend — Next.js on Vercel. App Router, server components where it made sense. Vercel for hosting because the deploy-on-push loop is frictionless and I was optimizing for solo velocity, not infra control. Backend — FastAPI on Render. I split the Python backend out rather than doing everything in Next API routes, because the heavy lifting (résumé parsing, the matching pipeline, scraping) is Python-native and I wanted it isolated from the frontend's request lifecycle. Database — Supabase + Prisma. Postgres under the hood. Prisma for the schema and type-safe queries; Supabase for the managed Postgres and some auth-adjacent data. Auth — Clerk. Handles sign-up, sessions, the whole identity layer. More on Clerk below, because it's where I lost the most hours. Payments — Stripe. Live mode, subscription tiers with a trial. Lookup keys drive tier resolution in the webhook so pricing changes don't require code changes. The actual "AI" — Gemini. This is the interesting part, so it gets its own section. Gemini does the real work The thing I care about most: the AI isn't a chatbot bolted on the side. Gemini makes the actual product decisions. Résumé reading: parse the PDF, extract real structure, and score it — not against keyword density, but against whether the claims are substantiated. The whole premise is honesty: most AI résumé tools keyword-stuff to beat the ATS, which backfires the second you're in an interview and can't back up your own résumé. Reclaim does the opposite — it flags where you're genuinely strong and where you're stretching. Matching: scores the résumé against
AI 资讯
Yelp’s OpenAI Deal Brings Local Reviews and Business Data to ChatGPT
Yelp has confirmed a licensing agreement with OpenAI that will extend Yelp content into AI platforms, including the OpenAI ecosystem powering ChatGPT. The deal positions Yelp’s reviews, ratings, photos and business information within a growing AI-driven local discovery experience, while opening a potential path for users to request quotes from local service providers through ChatGPT. The agreement is more consequential than a new search result format. Yelp is expanding its data-licensing strategy beyond conventional search surfaces, while ChatGPT gains access to a major source of local business content. For people asking an AI assistant where to eat, which contractor to contact or how a nearby business is rated, the quality, freshness and governance of the underlying data will matter as much as the answer itself. What the Yelp and OpenAI agreement covers In its February 2026 earnings and shareholder release , Yelp announced an agreement with OpenAI and described it as part of its AI transformation and strategy to license content for local discovery across AI ecosystems. That is the confirmed foundation of the development. Axios has reported the practical user-facing direction: ChatGPT will surface Yelp reviews, ratings, photos and other business details in responses to local queries. Yelp has also signaled that its Request a Quote capability could be integrated into ChatGPT in the near term, enabling users to initiate an inquiry with a service provider from the AI interface. Capability What the research supports Status Yelp content in ChatGPT Reviews, ratings, photos and other business details are expected to surface for local queries. Reported user-facing outcome of the confirmed licensing agreement Request a Quote in ChatGPT Users may be able to initiate quote requests with local service providers through the AI interface. Signaled for a future rollout Data timing and interface design Reporting describes real-time business data, but exact latency, update frequency
开发者
Falco — a from-scratch browser engine in ~36k lines of Rust (v0.1.0 release)
Hi everyone! I just released v0.1.0 of Falco — a browser engine I've been building in Rust on nights and weekends. No WebKit, no Gecko, no Chromium — every module is written from scratch in ~36,000 lines. 🔗 GitHub : https://github.com/poxk/Falco 🔗 Releases (prebuilt binaries for Linux/macOS/Windows): https://github.com/poxk/Falco/releases/tag/v0.1.0 What's inside All modules are from scratch, with no dependency on existing browser engines: HTML5 ( html5/ + html.rs ) Tokenizer — all 80 states of WHATWG §13.2.5, including script-data escape/double-escape state machine, attribute parsing with duplicate detection, named + numeric character references with Windows-1252 quirks table Tree builder — all 22 insertion modes of WHATWG §13.2.6, stack of open elements with scope algorithms (default/button/table/select/list-item), active formatting elements list, adoption agency algorithm (8-iteration outer loop with full inner loop and bookmark tracking), foster parenting for table content XML parser — strict, with namespace bindings, CDATA, PIs Encoding detection — BOM, HTTP Content-Type charset, <meta charset> , <meta http-equiv> , heuristic UTF-8/UTF-16 detection, decoders for UTF-8 / UTF-16LE / UTF-16BE / Windows-1252 innerHTML/outerHTML serialization — void elements, <template> contents fragment, raw text elements, full attribute value escaping DOM ( dom2/ ) NodeRef = Rc<RefCell<Node>> with parent/firstChild/lastChild/previousSibling/nextSibling pointers per spec MutationObserver with observe()/disconnect()/take_records(), subtree ancestor matching, attributeFilter Shadow DOM — attachShadow() with open/closed modes, host validation, named + default slots, fallback content, slot distribution (flatten tree algorithm) Custom elements — customElements.define() with name validation, observedAttributes, lifecycle callbacks (connected/disconnected/adopted/attributeChanged/form-associated), pending upgrades, customized built-in elements (is="...") Accessibility tree — parallel tree
AI 资讯
Judge denies xAI’s request to block Minnesota ban on ‘nudify’ apps
Despite a lawsuit from xAI, a Minnesota ban on apps that allow users to “nudify” images can move forward.
开发者
Angela Nissel faces down grief with a laugh
Angela Nissel's latest book, Good Grief, Pass the Bread, Mom Is Dead, is my kind of memoir. Sure, it's a deeply emotional tale about caring for a terminally ill parent. But it's delivered with the sort of gallows humor that I often turn to to get me through tough times. Of course, that sort of […]
AI 资讯
YouTuber Hank Green says his AI usage is ‘not healthy’
Green offered a remarkable apology, saying that "the level of dopamine that I've been getting from interacting with LLMs ... is not healthy for me or good for the world."
开发者
React Mastery Series – Day 14: React Hooks Deep Dive – Understanding useRef and useMemo
Welcome back to the React Mastery Series ! In the previous article, we explored useEffect Hook and learned how React handles side effects such as: API calls Timers Event listeners WebSocket connections Cleanup operations Today, we will explore two more powerful React Hooks: useRef and useMemo These Hooks are frequently used in production applications to: Access DOM elements Store values without triggering re-renders Optimize expensive calculations Improve application performance Understanding useRef Hook useRef is a React Hook that allows us to store a value that persists across renders without causing the component to re-render. Syntax: const reference = useRef ( initialValue ); The returned object looks like: { current : initialValue } The value is accessed using: reference . current useRef vs useState A common question: Why do we need useRef when we already have useState? The difference: useState useRef Updates trigger re-render Updates do not trigger re-render Used for UI data Used for storing values React tracks changes React does not track changes Example: const [ count , setCount ] = useState ( 0 ); Updating: setCount ( count + 1 ); causes: State Update | ↓ Component Re-render With useRef: const count = useRef ( 0 ); Updating: count . current ++ ; does: Value Updated | ↓ No Re-render Using useRef to Access DOM Elements One of the most common use cases of useRef is accessing DOM elements directly. Example: import { useRef } from " react " ; function SearchBox () { const inputRef = useRef (); function focusInput () { inputRef . current . focus (); } return ( < div > < input ref = { inputRef } /> < button onClick = { focusInput } > Focus Input </ button > </ div > ); } Flow: Button Click | ↓ focusInput() | ↓ inputRef.current | ↓ Input DOM Element | ↓ focus() Real-World Example: Login Page Imagine a banking login page. When the page loads: Open Login Page | ↓ Username Field Automatically Focused Implementation: useEffect (() => { usernameRef . current . focus ();
创业投融资
Should you still buy your next smartphone — or subscribe to it instead?
Apple's new Upgrade program is the latest sign that smartphone ownership is changing.
AI 资讯
Your DEX tool is probably overstating Uniswap v3 TVL by 25x
I shipped a bug into a paid API and it took me a while to see it, because nothing errored. Every response was a clean HTTP 200 with a confident number in it. The number was wrong by 25x . Here is the finding, the arithmetic, and how to check your own code in about thirty seconds. The measurement Uniswap v3, WETH/USDC on Base. Left column is what my API reported as TVL. Right column is what the pool contract actually holds — a plain balanceOf on each token, at the pool address. pool reported actually held overstated uniswapV3 0.01% $2,070,000 $215,646 9.6x uniswapV3 0.05% $73,600,000 $10,069,584 7.3x uniswapV3 0.30% $2,840,000,000 $111,513,855 25.5x uniswapV3 1.00% $14,800,000 $846,661 17.4x $2.84 billion in one pool on Base. Base's entire ecosystem TVL is a few billion dollars. That is what finally made me look — not a failing test, just a number too large to be true. Why it happens A v2 pool holds two piles of tokens and the price is the ratio between them. getReserves() returns the actual piles. Easy. A v3 pool concentrates liquidity into price ranges. It does not have "reserves" in the v2 sense. What it has is a liquidity value L at the current price P , and the standard way to make v3 math reusable is to compute the virtual reserves — the amounts a v2-style pool would need to behave identically right here: x_virtual = L / √P y_virtual = L × √P These are enormously useful. Feed them into the ordinary constant-product formula and you get correct swap outputs and correct price impact, which is why essentially every v3 integration computes them. They are also not tokens anyone owns . They describe the shape of the curve at the current price, not custody. Concentration is exactly the point of v3: a position spanning a narrow band behaves like a much larger v2 pool while holding far less capital. The 25x above is that leverage, showing up as a number I then mislabelled. My code did this: tvlUsd = 2 * reserveA * priceA // fine for v2, nonsense for v3 That line is corre
开发者
Stop Unnecessary Re-renders in React: A Practical Guide to Faster Applications
Introduction React is fast, but that doesn't mean every React application is. One of the most common performance problems—especially in growing applications—is unnecessary re-rendering . A small project with a few components may feel instant, but as your application grows, unnecessary renders can cause sluggish interfaces, input lag, excessive CPU usage, and poor user experience. The good news is that unnecessary re-renders are usually preventable once you understand why React re-renders components . In this article, we'll explore how React rendering works, learn how to identify performance bottlenecks, and apply practical optimization techniques such as React.memo , useMemo , useCallback , better state management, and component architecture. Whether you're building dashboards, e-commerce stores, SaaS products, or portfolio websites, these techniques will help you write more efficient React applications. Table of Contents Understanding React Rendering What Causes Unnecessary Re-renders? Identifying Performance Problems Optimizing with React.memo Optimizing Expensive Calculations with useMemo Preventing Function Recreation with useCallback State Colocation Splitting Components Optimizing Context Rendering Large Lists Using the React Profiler Best Practices Common Mistakes Performance Tips Security Considerations Accessibility Considerations SEO Considerations Real Project Example Conclusion Discussion Background Before optimizing anything, it's important to understand what React actually does. A render simply means React executes your component function to determine what the UI should look like. That does not always mean the browser updates the DOM . React compares the new Virtual DOM with the previous one and only updates the parts that actually changed. However, if many components re-render unnecessarily, React still has to: Execute component functions Recreate objects Recreate arrays Recreate event handlers Compare Virtual DOM trees All of that work adds up. Step
AI 资讯
AI Papers from Jul 06 - Jul 12 2026: A Practical Guide for Builders, Founders, and Developers
by Cipher Forge - Compounding-Asset Specialist @ HowiPrompt The past week has been a micro-boom in AI research. Five papers landed on arXiv, three on OpenReview, and a handful of industry pre-prints that together push the frontier on multimodal reasoning, efficient fine-tuning, and trustworthy LLM deployment. In this guide I'll: Distill the core contributions of each paper (no fluff, just the meat). Show you how to reproduce the key results with publicly available code or minimal re-implementation. Map the findings to real-world product pipelines - from data ingestion to inference scaling. Provide a reproducibility checklist so you can turn a paper into a compounding asset for your startup or product team. Grab a coffee, fire up your dev environment, and let's turn these seven papers into immediate value. 1. The Week in Review - Why These Papers Matter Date (2026) Venue Title Primary Claim Reported Gains Jul 06 arXiv "Mosaic-LLM: Structured Prompt Fusion for Multimodal Chains" A unified prompting language that stitches vision, audio, and text into a single chain of reasoning. 12.4 % higher VQA accuracy vs. Flamingo-3B on OKVQA. Jul 07 OpenReview "DeltaLoRA: Parameter-Efficient Fine-Tuning via Low-Rank Delta Updates" Introduces a delta-matrix on top of LoRA that reduces fine-tuning compute by 38 % without loss. 0.3 % BLEU drop on WMT-2025 while cutting GPU-hrs from 120->74. Jul 08 arXiv "TrustGuard: Certified Robustness for Retrieval-Augmented Generation" Formal robustness certificates for RAG pipelines under adversarial query perturbations. Guarantees 95 % success rate on adversarial SQuAD-2.0 attacks. Jul 09 arXiv "Neuro-Sketch: Zero-Shot Sketch-to-Image Generation with Diffusion-Guided Transformers" Leverages a diffusion prior to translate coarse sketches into photorealistic images without training on paired data. FID = 21.3 on QuickDraw-500, 2.8× better than prior zero-shot baselines. Jul 10 OpenReview "Meta-Prompt Engine (MPE): Automatic Prompt Synthesis for LLM
AI 资讯
My fresh OpenClaw install kept failing. The model wasn’t the problem.
I hit a failure pattern recently that’s way more common than people admit: install OpenClaw connect it to Ollama pull a decent local model test the model directly and it works run the first real agent turn and everything falls apart At that point, most people do the obvious thing: blame the model. Swap Qwen for Llama. Try a bigger model. Try a smaller model. Re-pull weights. Tweak quantization. Repeat. I think that’s usually the wrong first move. The real issue is often prompt baggage, context budgeting, or backend compatibility. Not the model itself. A direct Ollama prompt is a tiny test. An OpenClaw agent turn is not. The tell: direct Ollama works, OpenClaw fails I was reading a thread on r/openclaw where someone on Ubuntu Server said even a brand-new session with just hello could trigger the recurring error. The strange part was that the same model felt “lightning fast and great” when used directly through Ollama with a 4096 context. That’s the giveaway. If this works: curl http://localhost:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2.5-coder:14b", "messages": [ {"role": "user", "content": "hello"} ] }' but OpenClaw falls over on a normal turn, the model is probably not your first problem. You’re usually dealing with one of these: context blowout oversized system instructions too many skills loaded memory payloads getting injected every turn tool schema overhead output reservation settings that are too aggressive OpenAI-compat quirks in the backend That pattern shows up outside OpenClaw too. I’ve seen the same thing in n8n, Make, Zapier, and custom OpenAI-compatible agent stacks: the hello-world prompt passes, then the real automation fails because the production request is much heavier than anyone realized. A “fresh” OpenClaw install is not actually empty This is the part people miss. By the time your local model sees a real OpenClaw turn, it may already be carrying: system instructions tool definitions skill prompts me
科技前沿
What Is USB Tethering And How Do You Enable It For Mobile Hotspot?
There are times when a physical connection will perform better than a Wi-Fi hotspot. Here's when you want to use USB tethering, and how.
AI 资讯
How to Set Up a Free Custom Domain Email with Zoho Mail, Cloudflare, and Your Own Domain
How to Set Up a Free Custom Domain Email with Zoho Mail, Cloudflare, and Your Own Domain A custom email address like contact@yourdomain.com makes a huge difference when you are building a personal brand, portfolio, or freelance presence. It looks more professional than a free Gmail address, and it is surprisingly easy to set up using Zoho Mail’s free plan and your domain’s DNS. In this guide, I will walk through the exact flow I used to create a professional email address on a custom domain, without paying for a traditional business email suite. Important: This post uses placeholder values instead of real DNS records, IPs, or credentials. Replace the examples with the values Zoho shows for your own account. What you will need Before you begin, make sure you already have: A domain name (for example, yourdomain.com ) DNS access in Cloudflare or your domain provider A Zoho Mail account A few minutes to add DNS records and wait for propagation For this setup, I used: Website hosting: Vercel DNS: Cloudflare Email provider: Zoho Mail That combination works very well for a personal website or portfolio. Why use Zoho Mail? Zoho Mail is useful because it lets you create a professional email address using your own domain. On the free plan, Zoho supports a single domain with up to 5 users, 5 GB of storage per user, and web-only access. The free plan is available only in select data centers, so availability may vary by region. For a personal website, that is usually more than enough. The overall flow Here is the setup in simple terms: Buy a domain. Sign up for Zoho Mail. Add your existing domain. Verify that you own the domain using a TXT record. Add MX records so mail is delivered to Zoho. Add SPF, DKIM, and DMARC for email authentication. Test sending and receiving mail. Step 1: Sign up for Zoho Mail Go to Zoho Mail’s signup page and choose the free plan. During signup, Zoho will ask whether you want to add a new domain or an existing one. Since you already own the domain, ch