<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ju</title>
    <description>The latest articles on DEV Community by Ju (@soasme).</description>
    <link>https://dev.to/soasme</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F123337%2Fc3f794b4-59a6-44a9-8259-d3a37bd16be2.jpeg</url>
      <title>DEV Community: Ju</title>
      <link>https://dev.to/soasme</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/soasme"/>
    <language>en</language>
    <item>
      <title>Running Text-to-Speech Fully in the Browser with PocketTTS</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Wed, 28 Jan 2026 09:21:08 +0000</pubDate>
      <link>https://dev.to/soasme/running-text-to-speech-fully-in-the-browser-with-pockettts-2b0m</link>
      <guid>https://dev.to/soasme/running-text-to-speech-fully-in-the-browser-with-pockettts-2b0m</guid>
      <description>&lt;p&gt;Most text-to-speech (TTS) tools still work the same way they did years ago:&lt;br&gt;
send text to a server → wait → receive an audio file.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://quickeditvideo.com/tts/" rel="noopener noreferrer"&gt;QuickEditVideo&lt;/a&gt;, we took a very different approach.&lt;/p&gt;

&lt;p&gt;Our TTS tool runs entirely in the browser — no servers, no uploads, no API keys — using a compact neural model powered by PocketTTS and jax-js.&lt;/p&gt;

&lt;p&gt;In this post, I’ll break down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What PocketTTS is and why it’s a great fit for browsers&lt;/li&gt;
&lt;li&gt;How in-browser inference actually works&lt;/li&gt;
&lt;li&gt;Why client-side AI is a big deal for privacy, cost, and UX&lt;/li&gt;
&lt;li&gt;How modern JS + WASM tooling makes this possible today&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Live demo: &lt;a href="https://quickeditvideo.com/tts/" rel="noopener noreferrer"&gt;https://quickeditvideo.com/tts/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What Is PocketTTS?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PocketTTS&lt;/strong&gt; is a lightweight neural text-to-speech system designed for &lt;strong&gt;edge devices&lt;/strong&gt; and &lt;strong&gt;CPU-only inference&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Its design goals are very different from large cloud TTS models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Small model size&lt;/strong&gt; (around 300MB)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Fast CPU inference&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Deterministic output&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Low memory pressure&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Easy embedding&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes it ideal for environments like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Browsers&lt;/li&gt;
&lt;li&gt;  Desktop apps&lt;/li&gt;
&lt;li&gt;  Offline tools&lt;/li&gt;
&lt;li&gt;  Mobile devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of relying on massive autoregressive architectures, PocketTTS uses a &lt;strong&gt;streamlined acoustic model + vocoder pipeline&lt;/strong&gt; that trades a bit of expressiveness for speed, portability, and predictability — a trade-off that makes sense for real-time tools.&lt;/p&gt;
&lt;h2&gt;
  
  
  PocketTTS Inference Pipeline (High Level)
&lt;/h2&gt;

&lt;p&gt;Here’s what happens when you click “Generate” in the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Text input
  ↓
Text normalization
  ↓
Phoneme / token encoding
  ↓
Acoustic model (phonemes → features)
  ↓
Vocoder (features → waveform)
  ↓
WAV / audio buffer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every one of these steps runs locally — nothing leaves your device.&lt;/p&gt;

&lt;p&gt;No servers.&lt;br&gt;
No background jobs.&lt;br&gt;
No queueing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Run TTS in the Browser?
&lt;/h2&gt;

&lt;p&gt;Most “privacy-friendly” AI tools still send your data somewhere.&lt;/p&gt;

&lt;p&gt;With in-browser TTS:&lt;/p&gt;

&lt;p&gt;Text never leaves your machine&lt;br&gt;
Audio is generated locally&lt;br&gt;
Nothing is logged, stored, or transmitted&lt;/p&gt;

&lt;p&gt;This isn’t a policy — it’s a technical guarantee.&lt;/p&gt;

&lt;p&gt;ALso, Zero Latency, Zero Rate Limits! The speed you get depends only on the user’s device — not your backend capacity.&lt;/p&gt;

&lt;p&gt;Last but not least, From a builder’s perspective, this is huge.&lt;/p&gt;

&lt;p&gt;Running TTS in the browser means:&lt;/p&gt;

&lt;p&gt;no GPU servers&lt;br&gt;
no inference queues&lt;br&gt;
no autoscaling&lt;br&gt;
no “free tier abuse” issues&lt;/p&gt;

&lt;p&gt;Your infrastructure cost is zero. Yay!&lt;/p&gt;
&lt;h2&gt;
  
  
  How PocketTTS Runs in the Browser
&lt;/h2&gt;

&lt;p&gt;Browsers today are much more capable than most people realize. Yes, I'm talking about WebGPU! :)&lt;/p&gt;

&lt;p&gt;Here’s the stack that makes this work.&lt;/p&gt;
&lt;h3&gt;
  
  
  🧠 WebAssembly (WASM)
&lt;/h3&gt;

&lt;p&gt;PocketTTS is compiled to &lt;strong&gt;WebAssembly&lt;/strong&gt;, allowing near-native performance inside the browser.&lt;/p&gt;

&lt;p&gt;Why WASM matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fast numeric computation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Predictable memory layout&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SIMD support (where available)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No JS GC interference during inference&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes CPU-based neural inference viable — even on mid-range laptops.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      // Prepare text for TTS
      const [preparedText, framesAfterEos] = prepareTextPrompt(textToGenerate);
      const tokens = tokenizerRef.current.encode(preparedText);

      // Load voice embedding
      const voiceUrl = POCKET_TTS_VOICES[voiceToUse].url;
      const audioPromptData = safetensors.parse(await cachedFetch(voiceUrl));
      const audioPrompt = audioPromptData.tensors.audio_prompt;

      const voiceEmbed = np
        .array(audioPrompt.data as Float32Array&amp;lt;ArrayBuffer&amp;gt;, {
          shape: audioPrompt.shape,
          dtype: np.float32,
        })
        .slice(0)
        .astype(np.float16);

      // Create text embeddings
      const tokensAr = np.array(tokens, { dtype: np.uint32 });
      let embeds = modelRef.current.flowLM.conditionerEmbed.ref.slice(tokensAr);
      embeds = np.concatenate([voiceEmbed, embeds]);

      // Create streaming player and generate audio
      const player = createStreamingPlayer();

      try {
        await playTTS(player, tree.ref(modelRef.current), embeds, {
          framesAfterEos,
          seed: null,
          temperature: 0.7,
          lsdDecodeSteps: 1,
        });

        // Get the generated audio as WAV blob
        const audioBlob = player.toWav();
        const audioUrl = URL.createObjectURL(audioBlob);

        // Update the audio item with the generated URL
        setGeneratedAudios(prev =&amp;gt;
          prev.map(audio =&amp;gt;
            audio.id === audioId
              ? { ...audio, audioUrl, isGenerating: false }
              : audio
          )
        );
        if (autoPlayGeneratedAudio) {
          setLastAutoPlayedAudioId(audioId);
        }

      } finally {
        await player.close();
      }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function playTTS(
  player: AudioPlayer,
  model: PocketTTS,
  embeds: np.Array,
  {
    framesAfterEos = 0,
    seed = null,
    lsdDecodeSteps = 1,
    temperature = 0.7,
    noiseClamp = null,
    playChunk = false,
  }: Partial&amp;lt;PlayTTSOptions&amp;gt; = {},
): Promise&amp;lt;void&amp;gt; {
  let sequence = model.flowLM.bosEmb.ref.reshape([1, -1]); // [1, 32]
  let audioPromise: Promise&amp;lt;void&amp;gt; = Promise.resolve();

  if (seed === null) seed = Math.floor(Math.random() * 2 ** 32);
  let key = random.key(seed);

  try {
    let flowLMState = createFlowLMState(model.flowLM);
    let mimiState = createMimiDecodeState(model.mimi);
    let eosStep: number | null = null;

    console.log("Starting TTS generation...");
    let lastTimestamp = performance.now();

    for (let step = 0; step &amp;lt; 1000; step++) {
      let stepKey: np.Array;
      [key, stepKey] = random.split(key);
      const {
        latent,
        isEos,
        state: newFlowLMState,
      } = runFlowLMStep(
        tree.ref(model.flowLM),
        flowLMState,
        stepKey,
        step === 0 ? sequence.ref : sequence.ref.slice([-1]),
        step === 0 ? embeds.ref : null,
        flowLMState.kvCacheLen, // same as offset
        lsdDecodeSteps,
        temperature,
        noiseClamp,
      );
      flowLMState = newFlowLMState;

      const isEosData = await isEos.data();
      if (isEosData[0] &amp;amp;&amp;amp; eosStep === null) {
        console.log(`🛑 EOS at step ${step}!`);
        eosStep = step;
      }
      if (eosStep !== null &amp;amp;&amp;amp; step &amp;gt;= eosStep + framesAfterEos) {
        console.log(
          `Generation ended at step ${step}, ${framesAfterEos} frames after EOS.`,
        );
        latent.dispose();
        break;
      }

      sequence = np.concatenate([sequence, latent]);

      const timestamp = performance.now();
      console.log(
        `Generated step ${step} in ${(timestamp - lastTimestamp).toFixed(1)} ms`,
      );
      lastTimestamp = timestamp;

      let mimiInput = sequence.ref.slice([-1]);
      mimiInput = mimiInput
        .mul(model.flowLM.embStd.ref)
        .add(model.flowLM.embMean.ref);

      const [audio, newMimiState] = runMimiDecode(
        tree.ref(model.mimi),
        mimiState,
        mimiInput,
        step,
      );
      mimiState = newMimiState;

      const audioPcm = (await np
        .clip(audio.slice(0), -1, 1)
        .astype(np.float32)
        .data()) as Float32Array;
      if (audioPcm.length !== 1920) {
        throw new Error(
          `expected 1920 audio samples, got ${audioPcm.length}`,
        );
      }

      player.recordChunk(audioPcm);
      if (playChunk) {
        const lastAudioPromise = audioPromise;
        audioPromise = (async () =&amp;gt; {
          await lastAudioPromise;
          await player.playChunk(audioPcm);
        })();
      }
    }
  } finally {
    sequence.dispose();
    tree.dispose([model, embeds]);
    await audioPromise;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧮 Typed Arrays + Audio Buffers
&lt;/h3&gt;

&lt;p&gt;Instead of shuffling data through JSON or base64 blobs, the pipeline uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Float32Array&lt;/code&gt; / &lt;code&gt;Int16Array&lt;/code&gt; for tensors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Direct audio buffer synthesis&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimal copying between stages&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That keeps memory overhead low and performance stable.&lt;/p&gt;




&lt;h3&gt;
  
  
  📦 Model Caching (IndexedDB)
&lt;/h3&gt;

&lt;p&gt;The model is downloaded once and cached locally using &lt;strong&gt;IndexedDB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On repeat visits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No re-download&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Near-instant startup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Offline-friendly behavior&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is critical for UX when models are 300 MB in size.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Initialize WebGPU and load model
  useEffect(() =&amp;gt; {
    let isMounted = true;

    async function initializeModel() {
      let weightsAreCached = false;

      try {
        setLoadingProgress('Initializing WebGPU...');
        const devices = await init();

        if (!devices.includes('webgpu')) {
          throw new Error('WebGPU is not supported on this device. Please use a browser with WebGPU support (Chrome 113+, Edge 113+).');
        }

        defaultDevice('webgpu');

        if (!isMounted) return;

        try {
          const info = await opfs.info(MODEL_WEIGHTS_URL);
          weightsAreCached = info !== null;
        } catch (cacheInfoError) {
          console.warn('Failed to read cached model metadata:', cacheInfoError);
        }

        if (!isMounted) return;

        if (weightsAreCached) {
          setLoadingProgress('Loading cached model weights...');
          setIsWeightsDownloadInProgress(false);
          setWeightsDownloadPercent(null);
        } else {
          setLoadingProgress('Downloading model weights (300MB)...');
          setIsWeightsDownloadInProgress(true);
          setWeightsDownloadPercent(0);
        }

        const weightsData = await cachedFetch(
          MODEL_WEIGHTS_URL,
          undefined,
          (progress) =&amp;gt; {
            if (weightsAreCached || !isMounted) return;
            const total = progress.totalBytes ?? ESTIMATED_MODEL_WEIGHTS_SIZE;
            const percent = total &amp;gt; 0 ? Math.min(100, Math.round((progress.loadedBytes / total) * 100)) : 0;
            setWeightsDownloadPercent(percent);
          }
        );
        weightsRef.current = safetensors.parse(weightsData);

        if (!isMounted) return;

        if (!weightsAreCached) {
          setWeightsDownloadPercent(100);
          setIsWeightsDownloadInProgress(false);
        }

        setLoadingProgress('Loading model...');
        modelRef.current = fromSafetensors(weightsRef.current);

        if (!isMounted) return;

        // Load tokenizer
        setLoadingProgress('Loading tokenizer...');
        tokenizerRef.current = await tokenizers.loadSentencePiece(TOKENIZER_URL);

        if (!isMounted) return;

        setIsModelLoaded(true);
        setIsModelLoading(false);
        setLoadingProgress('');
        console.log('Pocket TTS model loaded successfully');

      } catch (err) {
        console.error('Failed to initialize Pocket TTS:', err);
        if (isMounted) {
          if (!weightsAreCached) {
            setIsWeightsDownloadInProgress(false);
            setWeightsDownloadPercent(null);
          }
          setError(err instanceof Error ? err.message : 'Failed to load TTS model');
          setIsModelLoading(false);
        }
      }
    }

    initializeModel();

    return () =&amp;gt; {
      isMounted = false;
    };
  }, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧪 Why This Approach Actually Works Now
&lt;/h2&gt;

&lt;p&gt;A few years ago, this would’ve been unrealistic.&lt;/p&gt;

&lt;p&gt;Today, we benefit from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Faster JS engines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mature WASM runtimes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better browser audio APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Smarter lightweight models like PocketTTS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’re not brute-forcing AI into the browser — we’re &lt;strong&gt;choosing models that fit the medium&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That mindset shift is the key.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Try It Yourself
&lt;/h2&gt;

&lt;p&gt;If you’re curious what modern browser-based TTS feels like:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://quickeditvideo.com/tts/?utm_source=dev.to"&gt;https://quickeditvideo.com/tts/&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No login&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No limits&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fully client-side&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instant playback&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Final Thought
&lt;/h2&gt;

&lt;p&gt;AI doesn’t have to live on massive servers.&lt;/p&gt;

&lt;p&gt;With the right models — like PocketTTS — and modern web runtimes, &lt;strong&gt;the browser becomes a serious inference platform&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This isn’t just about TTS.&lt;br&gt;&lt;br&gt;
It’s a glimpse of where web-native AI is heading.&lt;/p&gt;

&lt;p&gt;If you’re building tools for creators, educators, or everyday users — it’s worth paying attention.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>machinelearning</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I Wanted a Video Editor With No Paywalls, No Accounts, and No Cloud — So I Built One</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Tue, 06 Jan 2026 07:52:25 +0000</pubDate>
      <link>https://dev.to/soasme/i-wanted-a-video-editor-with-no-paywalls-no-accounts-and-no-cloud-so-i-built-one-5311</link>
      <guid>https://dev.to/soasme/i-wanted-a-video-editor-with-no-paywalls-no-accounts-and-no-cloud-so-i-built-one-5311</guid>
      <description>&lt;p&gt;I don’t like paywalls.&lt;br&gt;&lt;br&gt;
I don’t like subscriptions.&lt;br&gt;&lt;br&gt;
I don’t like signups.&lt;br&gt;&lt;br&gt;
I &lt;em&gt;really&lt;/em&gt; don’t like uploading my assets to someone else’s cloud just to trim a video.&lt;/p&gt;

&lt;p&gt;I just want to &lt;strong&gt;edit a video&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The same way I type text into a textarea.&lt;br&gt;&lt;br&gt;
Open → do the thing → export → done.&lt;/p&gt;

&lt;p&gt;No account.&lt;br&gt;&lt;br&gt;
No “start free trial”.&lt;br&gt;&lt;br&gt;
No “your file is being uploaded…”.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://quickeditvideo.com/app/" rel="noopener noreferrer"&gt;&lt;strong&gt;QuickEditVideo&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  The original sin of modern video editors
&lt;/h3&gt;

&lt;p&gt;Somewhere along the way, video editing became… heavy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Canva&lt;/strong&gt;: polished, powerful — but everything uploads. Your files live there, not with you.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CapCut&lt;/strong&gt;: does everything, installs everything, &lt;em&gt;ships everything&lt;/em&gt;. Bloated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DaVinci Resolve&lt;/strong&gt;: incredible tool — but slowly moving basic features behind gates.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All great products.&lt;br&gt;&lt;br&gt;
All solving problems I &lt;em&gt;don’t&lt;/em&gt; have.&lt;/p&gt;

&lt;p&gt;My problem is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I want to open a web page, edit a video, and export it.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s it.&lt;/p&gt;




&lt;h3&gt;
  
  
  My rules (non-negotiable)
&lt;/h3&gt;

&lt;p&gt;Before writing a single line of code, I wrote rules instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;❌ No paywall blocking editing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ No subscriptions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ No forced signups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ No cloud uploads&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ No local app installs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ Everything runs &lt;strong&gt;inside the browser&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ Your files stay &lt;strong&gt;on your machine&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ Editing is &lt;strong&gt;always free&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ Export &lt;strong&gt;in any resolution for free&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ Anything can be done &lt;em&gt;in browser for free&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;Editing should be as free as typing text.&lt;/p&gt;

&lt;p&gt;You don’t pay to open a textarea.&lt;br&gt;&lt;br&gt;
You don’t “subscribe” to write a paragraph.&lt;/p&gt;

&lt;p&gt;Why should trimming, or overlaying a video feel harder than writing a tweet?&lt;/p&gt;




&lt;h3&gt;
  
  
  So I made the tool I wanted
&lt;/h3&gt;

&lt;p&gt;Not the “best video editor”.&lt;br&gt;&lt;br&gt;
Not the “most features”.&lt;br&gt;&lt;br&gt;
Not an AI everything machine.&lt;/p&gt;

&lt;p&gt;Just:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Load local media&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Drag things around&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resize, trim, move on a timeline&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Export&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;No magic.&lt;br&gt;&lt;br&gt;
No dark patterns.&lt;br&gt;&lt;br&gt;
No lock-in.&lt;/p&gt;




&lt;h3&gt;
  
  
  Is this a good business?
&lt;/h3&gt;

&lt;p&gt;Honestly? I don’t know yet.&lt;/p&gt;

&lt;p&gt;But I &lt;em&gt;do&lt;/em&gt; know this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;People are tired of gates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;People miss simple tools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;People want ownership again&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this resonates with even a small group of creators, indie hackers, teachers, devs, or parents making quick videos — that’s enough.&lt;/p&gt;

&lt;p&gt;I didn’t build this to win a category.&lt;br&gt;&lt;br&gt;
I built it because I was annoyed.&lt;/p&gt;

&lt;p&gt;And sometimes, that’s the best reason to build anything.&lt;/p&gt;




&lt;p&gt;If you’re curious, it’s live.&lt;br&gt;&lt;br&gt;
If you hate it, that’s fair.&lt;br&gt;&lt;br&gt;
If you wish more tools worked like this — then we think the same way.&lt;/p&gt;

&lt;p&gt;Check it out: &lt;a href="https://quickeditvideo.com/app/" rel="noopener noreferrer"&gt;&lt;strong&gt;QuickEditVideo&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>privacy</category>
      <category>showdev</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Why Consistent Practice Beats Perfect Strategy</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Fri, 24 Oct 2025 09:06:52 +0000</pubDate>
      <link>https://dev.to/soasme/why-consistent-practice-beats-perfect-strategy-31km</link>
      <guid>https://dev.to/soasme/why-consistent-practice-beats-perfect-strategy-31km</guid>
      <description>&lt;p&gt;We all love strategy.&lt;br&gt;&lt;br&gt;
Funnel diagrams. PLG loops. Growth hacks.&lt;/p&gt;

&lt;p&gt;But after building &lt;a href="https://indie10k.com" rel="noopener noreferrer"&gt;&lt;strong&gt;Indie10k&lt;/strong&gt;&lt;/a&gt; — my “growth gym” for indie devs — I realized something uncomfortable:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;strategy doesn’t matter if you don’t show up every day.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Myth of the Perfect Plan
&lt;/h2&gt;

&lt;p&gt;When I started Indie10k, I thought success meant finding &lt;em&gt;the right playbook&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
I studied frameworks, copied funnels, and tweaked pricing models for weeks.&lt;/p&gt;

&lt;p&gt;None of it moved the needle.&lt;/p&gt;

&lt;p&gt;Why? Because growth doesn’t come from knowing the path — it comes from &lt;strong&gt;walking it&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Power of Consistency
&lt;/h2&gt;

&lt;p&gt;What actually worked was simple:&lt;br&gt;&lt;br&gt;
One rep. Every day.&lt;/p&gt;

&lt;p&gt;A small action: write a post, fix an onboarding bug, or talk to one user.&lt;br&gt;&lt;br&gt;
Each rep gave me data.&lt;br&gt;&lt;br&gt;
The data gave me clarity.&lt;br&gt;&lt;br&gt;
And clarity made strategy obvious.&lt;/p&gt;

&lt;p&gt;That’s when I learned:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Strategy is a compass.&lt;br&gt;&lt;br&gt;
Practice is the engine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can’t steer a car that isn’t moving.&lt;/p&gt;




&lt;h2&gt;
  
  
  For Indie Hackers, Momentum &amp;gt; Motivation
&lt;/h2&gt;

&lt;p&gt;If you’re building your first (or fifth) SaaS, don’t chase perfect strategy.&lt;br&gt;&lt;br&gt;
Chase momentum.&lt;/p&gt;

&lt;p&gt;Because &lt;strong&gt;momentum compounds&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
One rep turns into a streak.&lt;br&gt;&lt;br&gt;
A streak turns into insight.&lt;br&gt;&lt;br&gt;
Insight turns into growth.&lt;/p&gt;

&lt;p&gt;That’s how every “overnight success” actually happens — one boring, consistent day at a time.&lt;/p&gt;




&lt;h3&gt;
  
  
  💪 Rep Today
&lt;/h3&gt;

&lt;p&gt;Do &lt;strong&gt;one rep&lt;/strong&gt; — something small but repeatable.&lt;br&gt;&lt;br&gt;
Ship. Share. Learn. Repeat.&lt;/p&gt;

&lt;p&gt;Your strategy will get sharper the longer you stay in motion.&lt;/p&gt;

</description>
      <category>indiehackers</category>
      <category>saas</category>
      <category>productivity</category>
      <category>growth</category>
    </item>
    <item>
      <title>Why I Test Demand Before I Build (and You Probably Should Too)</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Fri, 24 Oct 2025 09:02:23 +0000</pubDate>
      <link>https://dev.to/soasme/why-i-test-demand-before-i-build-and-you-probably-should-too-2gba</link>
      <guid>https://dev.to/soasme/why-i-test-demand-before-i-build-and-you-probably-should-too-2gba</guid>
      <description>&lt;p&gt;I’ve lost count of how many side projects I’ve built that never found users.&lt;br&gt;&lt;br&gt;
Beautiful landing pages. Clever names. Clean code.&lt;br&gt;&lt;br&gt;
But no demand.&lt;/p&gt;

&lt;p&gt;Every indie hacker goes through that phase — building in excitement, then watching the numbers stay at &lt;strong&gt;zero&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;These days, I do the opposite.&lt;br&gt;&lt;br&gt;
Before I build anything, I test if people actually want it.&lt;/p&gt;

&lt;p&gt;That mindset led me to create &lt;a href="https://joinwaitlist.dev" rel="noopener noreferrer"&gt;&lt;strong&gt;JoinWaitlist.dev&lt;/strong&gt;&lt;/a&gt; — a tiny tool that helps founders &lt;strong&gt;launch a waitlist page in minutes&lt;/strong&gt; to validate their idea &lt;em&gt;before&lt;/em&gt; writing a single line of code.&lt;/p&gt;

&lt;p&gt;It’s basically a &lt;strong&gt;“fake door test”&lt;/strong&gt; made simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a one-page landing.&lt;/li&gt;
&lt;li&gt;Add a clear headline and&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ve lost count of how many side projects I’ve built that never found users.&lt;br&gt;&lt;br&gt;
Beautiful landing pages. Clever names. Clean code.&lt;br&gt;&lt;br&gt;
But no demand.&lt;/p&gt;

&lt;p&gt;Every indie hacker goes through that phase — building in excitement, then watching the numbers stay at &lt;strong&gt;zero&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;These days, I do the opposite.&lt;br&gt;&lt;br&gt;
Before I build anything, I test if people actually want it.&lt;/p&gt;

&lt;p&gt;That mindset led me to create &lt;strong&gt;JoinWaitlist.dev&lt;/strong&gt; — a tiny tool that helps founders &lt;strong&gt;launch a waitlist page in minutes&lt;/strong&gt; to validate their idea &lt;em&gt;before&lt;/em&gt; writing a single line of code.&lt;/p&gt;

&lt;p&gt;It’s basically a &lt;strong&gt;“fake door test”&lt;/strong&gt; made simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a one-page landing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a clear headline and signup form.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Share it in your communities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;See if anyone cares enough to join the waitlist.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If people sign up → you’ve got a real signal.&lt;br&gt;&lt;br&gt;
If not → you’ve saved yourself weeks or months of wasted effort.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Validation ≠ Perfection.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You don’t need fancy branding or pixel-perfect UI. A headline and a promise are enough to test interest.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Silence is data.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Zero sign-ups tells you something too — the idea, the audience, or the message isn’t resonating.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Momentum beats motivation.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Real feedback from even 3 sign-ups keeps you moving more than 30 days of overthinking.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Try It for Your Next Idea
&lt;/h2&gt;

&lt;p&gt;Next time you get that “what if…” idea, don’t open VS Code.&lt;br&gt;&lt;br&gt;
Open &lt;strong&gt;JoinWaitlist.dev&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Make a page.&lt;br&gt;&lt;br&gt;
Share it.&lt;br&gt;&lt;br&gt;
Learn fast.&lt;/p&gt;

&lt;p&gt;Because building what people &lt;em&gt;want&lt;/em&gt; starts with knowing &lt;em&gt;who wants it.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 Discussion
&lt;/h3&gt;

&lt;p&gt;Do you test ideas before building?&lt;br&gt;&lt;br&gt;
What’s your go-to validation method — waitlists, mock sales, or something else?&lt;/p&gt;

</description>
      <category>saas</category>
      <category>validation</category>
      <category>startup</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>Momentum Beats Motivation</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Thu, 23 Oct 2025 08:57:46 +0000</pubDate>
      <link>https://dev.to/soasme/momentum-beats-motivation-kbc</link>
      <guid>https://dev.to/soasme/momentum-beats-motivation-kbc</guid>
      <description>&lt;p&gt;I used to wait for motivation. That spark, that burst of energy that made me  &lt;em&gt;want&lt;/em&gt;  to ship something.&lt;/p&gt;

&lt;p&gt;But here’s what I’ve learned building  &lt;a href="https://indie10k.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Indie10k&lt;/strong&gt;&lt;/a&gt;: motivation is fickle. Momentum is the real compound interest.&lt;/p&gt;

&lt;p&gt;When I ship one small rep — fix a bug, improve a headline, reply to one user — I feel a small win. That win stacks. Tomorrow’s rep gets easier. Soon, I’m not chasing motivation; I’m riding momentum.&lt;/p&gt;

&lt;p&gt;The days I feel unmotivated? Those are actually the most important ones. Because when I ship  &lt;em&gt;anyway&lt;/em&gt;, I keep the streak alive. Momentum doesn’t care how I feel — it just wants motion.&lt;/p&gt;

&lt;p&gt;Indie10k is built around that idea. You don’t need a big plan, a fancy dashboard, or a productivity ritual. You just need  &lt;strong&gt;one rep a day&lt;/strong&gt;. The rest compounds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rep
&lt;/h3&gt;

&lt;p&gt;Ship one thing today — no matter how small. Momentum will take care of tomorrow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://indie10k.com/" rel="noopener noreferrer"&gt;Keep Going!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>saas</category>
      <category>startup</category>
      <category>growth</category>
    </item>
    <item>
      <title>🧱 Progress Shared Compounds Faster Than Progress Hidden</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Wed, 22 Oct 2025 19:18:15 +0000</pubDate>
      <link>https://dev.to/soasme/progress-shared-compounds-faster-than-progress-hidden-nm1</link>
      <guid>https://dev.to/soasme/progress-shared-compounds-faster-than-progress-hidden-nm1</guid>
      <description>&lt;p&gt;We indie hackers love polishing.&lt;br&gt;&lt;br&gt;
We tweak buttons, fix margins, rewrite the copy.&lt;br&gt;&lt;br&gt;
All waiting for the “perfect” launch day.&lt;/p&gt;

&lt;p&gt;But here’s the truth: &lt;strong&gt;nobody connects with perfection.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
People connect with &lt;em&gt;momentum.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every time you share a screenshot, chart, or scrappy prototype, you’re sending one message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’m building for real.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That builds trust.&lt;br&gt;&lt;br&gt;
And trust compounds faster than polish ever will.&lt;/p&gt;

&lt;p&gt;One rough screenshot does more for your credibility than a hundred “launch soon” tweets.&lt;br&gt;&lt;br&gt;
Because progress — even messy progress — is proof.&lt;/p&gt;

&lt;p&gt;When you show the climb, people root for you.&lt;br&gt;&lt;br&gt;
When you hide it, they forget you exist.&lt;/p&gt;

&lt;p&gt;Momentum is magnetic. It pulls in early adopters. It reminds you that you’re moving.&lt;br&gt;&lt;br&gt;
Every “shipped this today” post is a rep — and every rep builds trust.&lt;/p&gt;




&lt;h3&gt;
  
  
  💪 Rep of the Day
&lt;/h3&gt;

&lt;p&gt;Take one screenshot of what you built today — UI, code, or chart —&lt;br&gt;&lt;br&gt;
and post it with one simple line:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Shipped this today to make X easier.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let your momentum speak for itself. &lt;a href="https://indie10k.com" rel="noopener noreferrer"&gt;Keep Going at indie10k&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;💬 &lt;strong&gt;Your turn:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Do you share your in-progress builds, or wait until everything’s polished? Drop your latest screenshot in the comments — let’s cheer each other on.&lt;/p&gt;

</description>
      <category>motivation</category>
      <category>productivity</category>
      <category>startup</category>
    </item>
    <item>
      <title>I Feel Many SaaS Have “Bad Taste”</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Mon, 13 Oct 2025 07:57:57 +0000</pubDate>
      <link>https://dev.to/soasme/i-feel-many-saas-have-bad-taste-43nb</link>
      <guid>https://dev.to/soasme/i-feel-many-saas-have-bad-taste-43nb</guid>
      <description>&lt;p&gt;Linus Torvalds often gets mad at “bad taste” code —&lt;br&gt;
lazy, inconsistent, or too clever for no reason.&lt;/p&gt;

&lt;p&gt;He values code that’s blunt, explicit, and honest.&lt;br&gt;
Readable over “smart.” Maintainable over elegant.&lt;/p&gt;

&lt;p&gt;I think we’ve lost that kind of taste in product building.&lt;/p&gt;

&lt;p&gt;Most SaaS today ships fast — but without vibe.&lt;br&gt;
No rhythm. No restraint. Just endless feature drops.&lt;/p&gt;

&lt;p&gt;“Vibe coding” used to mean care.&lt;br&gt;
You built something that felt right.&lt;br&gt;
Now it just means “ship something before Friday.”&lt;/p&gt;

&lt;p&gt;AI writes, frameworks deploy, and 90% of what ships feels… soulless.&lt;br&gt;
Everything works, but nothing feels alive.&lt;/p&gt;

&lt;p&gt;That’s why I built &lt;a href="https://indie10k.com?utm_source=devto" rel="noopener noreferrer"&gt;Indie10k&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s my attempt to bring taste back into building.&lt;/p&gt;

&lt;p&gt;Not through rules or frameworks —&lt;br&gt;
but through small, daily reps that remind you what matters:&lt;br&gt;
clarity, intention, rhythm, momentum.&lt;/p&gt;

&lt;p&gt;Indie10k gives you one growth task a day.&lt;br&gt;
Tiny, human-paced, and thoughtful —&lt;br&gt;
because good products are built with repetition, not rush.&lt;/p&gt;

&lt;p&gt;We don’t need faster builders.&lt;br&gt;
We need builders with better taste.&lt;/p&gt;

&lt;p&gt;What do you think? Can a SaaS still have taste — or has “move fast” killed that part of the craft?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The TenK Manifesto — Why Indie Founders Need a Movement</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Tue, 07 Oct 2025 08:38:04 +0000</pubDate>
      <link>https://dev.to/soasme/the-tenk-manifesto-why-indie-founders-need-a-movement-11bk</link>
      <guid>https://dev.to/soasme/the-tenk-manifesto-why-indie-founders-need-a-movement-11bk</guid>
      <description>&lt;h2&gt;
  
  
  🧭 The TenK Manifesto — Why Indie Founders Need a Movement, Not Another App
&lt;/h2&gt;

&lt;p&gt;Every week, I see indie devs ask the same questions:&lt;br&gt;&lt;br&gt;
“How do I find my first users?”&lt;br&gt;&lt;br&gt;
“When should I start charging?”&lt;br&gt;&lt;br&gt;
“What should I build next?”&lt;/p&gt;

&lt;p&gt;And every week, I see the same outcome:&lt;br&gt;&lt;br&gt;
They overthink. Overbuild. Burn out.&lt;br&gt;&lt;br&gt;
Then another side project joins the graveyard.&lt;/p&gt;

&lt;p&gt;I’ve been there more times than I want to admit.&lt;/p&gt;

&lt;p&gt;That’s why I created &lt;strong&gt;Indie10k&lt;/strong&gt; — a place where indie founders can &lt;em&gt;practice&lt;/em&gt; reaching $10k MRR through daily, small, repeatable reps.&lt;/p&gt;

&lt;p&gt;But recently, I realized something deeper:&lt;br&gt;&lt;br&gt;
An app isn’t enough.&lt;/p&gt;

&lt;p&gt;We don’t just need another tool.&lt;br&gt;&lt;br&gt;
We need &lt;strong&gt;a shared set of principles&lt;/strong&gt; — the indie equivalent of the Agile Manifesto.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧩 What Is the TenK Manifesto?
&lt;/h3&gt;

&lt;p&gt;It’s a declaration for indie founders who believe success isn’t a lucky launch or viral tweet — it’s the &lt;em&gt;compounding result of consistent reps.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We are uncovering better ways of reaching $10k MRR as indie founders&lt;/strong&gt; by showing up daily, compounding small wins, and helping others do the same.&lt;/p&gt;

&lt;p&gt;Through this work, we have come to value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Consistent practice&lt;/strong&gt; over perfect strategy&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Small, shippable reps&lt;/strong&gt; over grand unstarted plans&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Momentum through streaks&lt;/strong&gt; over bursts of unsustainable effort&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Direct customer conversations&lt;/strong&gt; over secondhand advice&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Evidence from action&lt;/strong&gt; over assumptions from theory&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Sharing progress openly&lt;/strong&gt; over building alone in silence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While there’s value in the items on the right, we value the items on the left more.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  💡 Why It Matters
&lt;/h3&gt;

&lt;p&gt;The indie world has become noisy.&lt;br&gt;&lt;br&gt;
Everyone talks about frameworks, funnels, hacks, and AI shortcuts.&lt;/p&gt;

&lt;p&gt;But nobody’s teaching the fundamentals —&lt;br&gt;&lt;br&gt;
how to build momentum, how to stay consistent, how to learn from action instead of theory.&lt;/p&gt;

&lt;p&gt;Just like Agile reshaped software development,&lt;br&gt;&lt;br&gt;
we need a new movement to reshape &lt;em&gt;how indie founders build.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The TenK Manifesto is that foundation — a call to stop overthinking, start practicing, and measure success not by followers or features, but by the streaks of daily progress we show up for.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚀 Join the Movement
&lt;/h3&gt;

&lt;p&gt;I drafted this manifesto in Tongariro, New Zealand — in the rain, looking at snow and volcano peaks — and signed it as the first believer.&lt;/p&gt;

&lt;p&gt;Now, I’m sharing it with the community that understands it best: devs who build things that matter.&lt;/p&gt;

&lt;p&gt;✍️ &lt;strong&gt;Sign the Manifesto:&lt;/strong&gt; &lt;a href="https://indie10k.com/manifesto" rel="noopener noreferrer"&gt;https://indie10k.com/manifesto&lt;/a&gt;&lt;br&gt;&lt;br&gt;
👋 &lt;strong&gt;Author:&lt;/strong&gt; Ju Lin, Founder of Indie10k&lt;br&gt;&lt;br&gt;
© 2025 — This declaration may be freely copied in full with this notice.&lt;/p&gt;

</description>
      <category>indiehackers</category>
      <category>saas</category>
      <category>startup</category>
    </item>
    <item>
      <title>✍️ Drafting the TenK Manifesto</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Sat, 04 Oct 2025 11:14:24 +0000</pubDate>
      <link>https://dev.to/soasme/drafting-the-tenk-manifesto-2llm</link>
      <guid>https://dev.to/soasme/drafting-the-tenk-manifesto-2llm</guid>
      <description>&lt;p&gt;Most of us have read the &lt;strong&gt;Agile Manifesto&lt;/strong&gt; — short, sharp, and surprisingly timeless. It gave developers something to rally behind that wasn’t a tool, a process, or a trend, but a set of values.&lt;/p&gt;

&lt;p&gt;I’ve been building &lt;a href="https://indie10k.com" rel="noopener noreferrer"&gt;Indie10k&lt;/a&gt;, which is kind of like a “growth gym” for indie founders. The core idea is simple: &lt;strong&gt;daily reps compound into momentum&lt;/strong&gt;. Not theory, not playbooks, not frameworks we abandon after two weeks. Just consistent practice.&lt;/p&gt;

&lt;p&gt;That led me to ask: what if indie SaaS builders had their own manifesto?&lt;/p&gt;

&lt;p&gt;So I drafted one.&lt;/p&gt;




&lt;h2&gt;
  
  
  The TenK Manifesto
&lt;/h2&gt;

&lt;p&gt;We are uncovering better ways of reaching $10k MRR as indie founders&lt;br&gt;&lt;br&gt;
by showing up daily, compounding small wins, and helping others do the same.&lt;/p&gt;

&lt;p&gt;Through this work we have come to value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Consistent practice &lt;strong&gt;over&lt;/strong&gt; perfect strategy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Small, shippable reps &lt;strong&gt;over&lt;/strong&gt; grand unstarted plans&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Momentum through streaks &lt;strong&gt;over&lt;/strong&gt; bursts of unsustainable effort&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Direct customer conversations &lt;strong&gt;over&lt;/strong&gt; secondhand advice&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Evidence from action &lt;strong&gt;over&lt;/strong&gt; assumptions from theory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sharing progress openly &lt;strong&gt;over&lt;/strong&gt; building alone in silence&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is, while there is value in the items on the right,&lt;br&gt;&lt;br&gt;
we value the items on the left more.&lt;/p&gt;




&lt;h2&gt;
  
  
  How You Can Join
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you’d like to &lt;strong&gt;co-author&lt;/strong&gt;, just leave a suggestion in the &lt;a href="https://docs.google.com/document/d/10OjVTWtOpw_h6XZnXTOyZpcU6E4f44On-0bNwFFDQ7Y/edit?tab=t.0" rel="noopener noreferrer"&gt;Google Doc&lt;/a&gt;. If it’s adopted, your name will be added to the Authors section.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you’d like to &lt;strong&gt;sign it&lt;/strong&gt;, you can add your name, email, and (optional) product link to be listed as a Signatory.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I don’t think this will solve everything. But I do think indie founders deserve something to point to and say, &lt;em&gt;this is how we build&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;👉 Would you sign the TenK Manifesto? &lt;a href="https://indie10k.com/manifesto" rel="noopener noreferrer"&gt;indie10k.com/manifesto&lt;/a&gt;&lt;/p&gt;

</description>
      <category>indiehackers</category>
      <category>saas</category>
      <category>startup</category>
    </item>
    <item>
      <title>Indie10k: Why I Built the “Arc” to Turn Goals Into Growth</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Fri, 26 Sep 2025 10:15:56 +0000</pubDate>
      <link>https://dev.to/soasme/indie10k-why-i-built-the-arc-to-turn-goals-into-growth-4h6m</link>
      <guid>https://dev.to/soasme/indie10k-why-i-built-the-arc-to-turn-goals-into-growth-4h6m</guid>
      <description>&lt;p&gt;Most side projects die the same way:&lt;br&gt;&lt;br&gt;
You set a big goal, jot down some tasks, and then… momentum fades.&lt;/p&gt;

&lt;p&gt;I’ve been there more times than I can count (65 dead projects, to be exact). This time, I wanted a system that didn’t just track &lt;em&gt;tasks&lt;/em&gt; — but kept me locked onto &lt;em&gt;progress&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That’s where the &lt;strong&gt;Arc&lt;/strong&gt; comes in.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s an Arc?
&lt;/h2&gt;

&lt;p&gt;In Indie10k, an &lt;strong&gt;Arc&lt;/strong&gt; is the container for your growth journey.&lt;/p&gt;

&lt;p&gt;It connects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;North Star Goal&lt;/strong&gt; (something measurable, like &lt;em&gt;reach 1k newsletter subs&lt;/em&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;metric + target value&lt;/strong&gt; (your scoreboard).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A sequence of &lt;strong&gt;steps&lt;/strong&gt; (the &lt;a href="https://indie10k.com/tenk6?utm_source=devto" rel="noopener noreferrer"&gt;TenK 6 Methodology&lt;/a&gt;: List → Pick → Ship → Ask → Measure → Share).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as a structured habit-builder for indie growth. Instead of vague “do marketing” tasks, you’re running small experiments tied to your goal — and stacking evidence every step of the way.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why It’s Different From a To-Do List
&lt;/h2&gt;

&lt;p&gt;A checklist can make you feel productive while moving you nowhere.&lt;/p&gt;

&lt;p&gt;An Arc is different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It ties every action back to one guiding metric.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It creates natural accountability (you can’t “check off” growth until you ship + measure).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It builds a story you can share — your evidence, your loops, your milestones.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  My Own Arc Right Now
&lt;/h2&gt;

&lt;p&gt;Today, my Arc looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; 100 active users in Indie10k&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Metric:&lt;/strong&gt; number of completed loops by real users&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Loops:&lt;/strong&gt; posting on Indie Hackers, Product Hunt, Dev.to, and running distribution tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I write this, I’m sitting at &lt;strong&gt;98 signups&lt;/strong&gt;. Two more people and I cross the first big milestone. 🚀&lt;/p&gt;

&lt;p&gt;It’s not life-changing revenue yet, but it’s &lt;em&gt;proof of momentum&lt;/em&gt;. That’s what the Arc keeps me focused on — the compounding effect of small loops.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I’m Sharing This
&lt;/h2&gt;

&lt;p&gt;If you’re a developer building a project, I’d love your feedback:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Does the idea of an “Arc” make sense for guiding growth?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Would you actually track your side project this way?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m building &lt;a href="https://indie10k.com?utm_source=devto" rel="noopener noreferrer"&gt;Indie10k&lt;/a&gt; in public, so early thoughts from fellow devs are incredibly valuable.&lt;/p&gt;




&lt;p&gt;👉 Check out Indie10k if you want to try running your own Arc.&lt;br&gt;&lt;br&gt;
Think of it as a daily growth gym — but instead of push-ups, you’re shipping loops.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>startup</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>Stop Polishing Pixels. Start Bumping Versions.</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Thu, 25 Sep 2025 23:14:57 +0000</pubDate>
      <link>https://dev.to/soasme/stop-polishing-pixels-start-bumping-versions-7ge</link>
      <guid>https://dev.to/soasme/stop-polishing-pixels-start-bumping-versions-7ge</guid>
      <description>&lt;h2&gt;
  
  
  Indie devs, I see you.
&lt;/h2&gt;

&lt;p&gt;Pixel-pushing that landing page. Debating if that button should be 1px taller. Sitting on 0.100.0 releases because “it’s not 1.0 ready.”&lt;/p&gt;

&lt;p&gt;Guess what? Nobody cares. Users don’t read semver like you do. They care if you ship, if it works, and if you improve fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fear of 1.0
&lt;/h2&gt;

&lt;p&gt;I’ve been there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“1.0 feels permanent.”&lt;/li&gt;
&lt;li&gt;“What if it’s buggy?”&lt;/li&gt;
&lt;li&gt;“I’ll look unprofessional.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That fear freezes momentum. You end up stuck polishing details that don’t move your MRR.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flip the Mindset
&lt;/h2&gt;

&lt;p&gt;What if you treated version bumps as momentum markers instead of perfection badges?&lt;/p&gt;

&lt;p&gt;1.0.0 — The first time someone pays.&lt;/p&gt;

&lt;p&gt;2.0.0 — You fix a core workflow.&lt;/p&gt;

&lt;p&gt;3.0.0 — You overhaul onboarding.&lt;/p&gt;

&lt;p&gt;Every bump is a story to tell your users, your community, your future self. Each one says: this thing is alive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shipping &amp;gt; Perfecting
&lt;/h2&gt;

&lt;p&gt;So stop hiding behind .0.100.0.&lt;/p&gt;

&lt;p&gt;Bump majors often.&lt;/p&gt;

&lt;p&gt;Celebrate progress.&lt;/p&gt;

&lt;p&gt;Keep momentum rolling.&lt;/p&gt;

&lt;p&gt;Because SaaS isn’t about perfect pixels. It’s about compounding small wins until one day you look back and realize: wow, this thing grew up.&lt;/p&gt;

&lt;p&gt;🚀 At &lt;a href="https://indie10k.com?utm_source=devto" rel="noopener noreferrer"&gt;Indie10k&lt;/a&gt;, we help indie devs build momentum by turning growth into repeatable loops—not perfection traps. If you’re ready to stop stalling at 0.100.0 and start stacking wins toward $10k MRR, join us and start your first loop today.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>indiehackers</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Don’t Mercilessly Add AI Just to Look Cool</title>
      <dc:creator>Ju</dc:creator>
      <pubDate>Thu, 25 Sep 2025 21:07:34 +0000</pubDate>
      <link>https://dev.to/soasme/dont-mercilessly-add-ai-just-to-look-cool-h8m</link>
      <guid>https://dev.to/soasme/dont-mercilessly-add-ai-just-to-look-cool-h8m</guid>
      <description>&lt;p&gt;I almost fell into the trap.&lt;br&gt;&lt;br&gt;
A user told me: &lt;em&gt;“Writing a North Star goal feels hard.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And my first reaction? &lt;em&gt;“No problem, I’ll slap in an AI button and it’ll magically write one for them.”&lt;/em&gt; ✨&lt;/p&gt;

&lt;p&gt;Spoiler: it didn’t work. The AI goals were fluffy, generic, and sometimes completely wrong. It looked shiny on the surface, but it didn’t actually solve the user’s problem. In fact, it made things worse.&lt;/p&gt;




&lt;h2&gt;
  
  
  The temptation is real
&lt;/h2&gt;

&lt;p&gt;AI is like glitter right now. Sprinkle a bit, and suddenly your product feels trendy. “Ooooh, it has AI!”&lt;/p&gt;

&lt;p&gt;But here’s the catch: &lt;strong&gt;if it doesn’t reduce friction, save real time, or give users genuine clarity—it’s just noise.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I forced AI into my product, it created a false sense of “magic” instead of addressing the real struggle: blank-page paralysis.&lt;/p&gt;




&lt;h2&gt;
  
  
  The boring solution that worked
&lt;/h2&gt;

&lt;p&gt;Instead of giving users an AI-generated goal, I stripped it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One metric.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One target.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;“User signups → 100.”&lt;br&gt;&lt;br&gt;
“MRR → $50 this loop.”&lt;/p&gt;

&lt;p&gt;Not fancy. Not “intelligent.” Just usable.&lt;/p&gt;




&lt;h2&gt;
  
  
  The lesson
&lt;/h2&gt;

&lt;p&gt;Every time I get the itch to bolt on AI just to impress people, I remind myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI should be the assistant, never the boss.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Features exist to help users move forward, not to pad a product demo.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simple &amp;gt; Cool. Always.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Curious about your take
&lt;/h2&gt;

&lt;p&gt;Have you ever been tempted (or pressured) to throw AI into your product when a simpler solution was sitting right there?&lt;/p&gt;

&lt;p&gt;👉 I’m building &lt;a href="https://indie10k.com?utm_source=devto" rel="noopener noreferrer"&gt;Indie10k&lt;/a&gt; to help indie devs reach $10k MRR without drowning in overhead. If you’ve got thoughts on when AI &lt;em&gt;is&lt;/em&gt; actually useful, I’d love to hear them.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>saas</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
