<?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: Berat Bozkurt</title>
    <description>The latest articles on DEV Community by Berat Bozkurt (@beratbozkurt0).</description>
    <link>https://dev.to/beratbozkurt0</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F283261%2Fe92d2215-0f50-46a2-b5a9-4ccaa1f4adb7.jpg</url>
      <title>DEV Community: Berat Bozkurt</title>
      <link>https://dev.to/beratbozkurt0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/beratbozkurt0"/>
    <language>en</language>
    <item>
      <title>Building GitHub OAuth device flow in a Node.js CLI</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Thu, 18 Jun 2026 14:22:38 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/building-github-oauth-device-flow-in-a-nodejs-cli-6e1</link>
      <guid>https://dev.to/beratbozkurt0/building-github-oauth-device-flow-in-a-nodejs-cli-6e1</guid>
      <description>&lt;p&gt;When building a CLI tool that needs GitHub access, you have three options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ask users to create a personal access token manually (bad UX)&lt;/li&gt;
&lt;li&gt;Redirect to a web page (requires a server)&lt;/li&gt;
&lt;li&gt;Use the OAuth device flow&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The device flow is what the GitHub CLI itself uses. Users run one command, a URL and code appear, they open it in any browser. No server, no copy-pasting tokens. Here's how to implement it cleanly.&lt;/p&gt;




&lt;h3&gt;
  
  
  The flow in three steps
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. POST /login/device/code
   → returns: device_code, user_code, verification_uri, expires_in, interval

2. Show the user:
   "Open https://github.com/login/device/activate and enter: XXXX-YYYY"

3. Poll POST /login/oauth/access_token every {interval} seconds
   → returns: access_token (when user completes) or error codes (keep polling)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation is ~100 lines. Most of the complexity is in handling the polling responses correctly.&lt;/p&gt;




&lt;h3&gt;
  
  
  Polling response codes
&lt;/h3&gt;

&lt;p&gt;This is the part most tutorials skip. The responses aren't HTTP errors — they come back as &lt;code&gt;200 OK&lt;/code&gt; with an &lt;code&gt;error&lt;/code&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PollResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;token_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authorization_pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;   &lt;span class="c1"&gt;// user hasn't authorized yet — keep polling&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slow_down&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;// increase interval by 5s&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expired_token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;           &lt;span class="c1"&gt;// time's up — restart the flow&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;access_denied&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;           &lt;span class="c1"&gt;// user denied — stop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Treating all of these as errors breaks the UX. &lt;code&gt;authorization_pending&lt;/code&gt; just means "not yet" — keep the spinner going.&lt;/p&gt;




&lt;h3&gt;
  
  
  The polling loop
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;pollForToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deviceCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;intervalSecs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;intervalSecs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://github.com/login/oauth/access_token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;client_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;device_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;deviceCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;grant_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;urn:ietf:params:oauth:grant-type:device_code&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;access_token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slow_down&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expired_token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization timed out. Run auth login again.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;access_denied&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization denied.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// authorization_pending: continue loop&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Token storage
&lt;/h3&gt;

&lt;p&gt;Write to &lt;code&gt;~/.toolname/config.json&lt;/code&gt; and immediately chmod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chmodSync&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;homedir&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;os&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;join&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;configPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;homedir&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.releasehub&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;config.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;githubToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;chmodSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;0o600&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// owner read/write only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most CLIs skip the chmod and leave the token world-readable. Don't.&lt;/p&gt;




&lt;p&gt;The full implementation is in &lt;a href="https://github.com/berat/releasehub/blob/main/packages/cli/src/commands/auth.ts" rel="noopener noreferrer"&gt;ReleaseHub&lt;/a&gt; — a CLI for generating release notes from GitHub PRs. The auth module is standalone if you want to adapt it.&lt;/p&gt;

</description>
      <category>node</category>
      <category>github</category>
      <category>typescript</category>
      <category>cli</category>
    </item>
    <item>
      <title>How I use LLMs for structured classification without getting garbage output</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Mon, 15 Jun 2026 07:58:08 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/how-i-use-llms-for-structured-classification-without-getting-garbage-output-29mk</link>
      <guid>https://dev.to/beratbozkurt0/how-i-use-llms-for-structured-classification-without-getting-garbage-output-29mk</guid>
      <description>&lt;p&gt;I've been using LLMs to classify GitHub pull requests into changelog categories. The goal: automatically decide if a PR is a feature, bugfix, breaking change, or internal noise.&lt;/p&gt;

&lt;p&gt;It took several iterations to get consistent output. Here's what actually worked.&lt;/p&gt;




&lt;h3&gt;
  
  
  The problem with direct classification
&lt;/h3&gt;

&lt;p&gt;The naive approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Classify this PR: feature / bugfix / breaking / internal.

PR title: "Update auth middleware"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hit rate was ~70%. The model pattern-matched on title keywords instead of understanding intent. Every "update" became "improvement", every "fix" became "bugfix" — even when the PR body told a completely different story.&lt;/p&gt;




&lt;h3&gt;
  
  
  What worked: reason first, classify second
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;PR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;title,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;labels,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;carefully.&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Step&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;one&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sentence,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;explain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;what&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;change&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;does&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;user.&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="err"&gt;If&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;has&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;no&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;end-user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;impact&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;refactor,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;dependency&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;bump,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;change),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;say&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"no end-user impact"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;explicitly.&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Step&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Classify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;one&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;feature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;improvement&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;bugfix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;breaking&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;internal&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"user_impact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hit rate: ~92% on the same test set.&lt;/p&gt;

&lt;p&gt;The key insight: forcing the model to articulate user impact before labeling makes it actually read the PR body. A PR titled "refactor auth middleware" with a body describing a logout race condition gets correctly classified as "bugfix" — not "internal".&lt;/p&gt;




&lt;h3&gt;
  
  
  Batching for cost and speed
&lt;/h3&gt;

&lt;p&gt;One request per PR is expensive and slow. Batching 20 PRs per request with structured JSON output works much better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
Classify each of these &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; pull requests.

PRs:
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;pr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`
[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]
Title: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
Labels: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;
Body: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;

Return a JSON array with &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; objects, each with:
- index: number
- user_impact: one sentence or "no end-user impact"  
- category: "feature" | "improvement" | "bugfix" | "breaking" | "internal"
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cost per analysis drops ~10x compared to one-request-per-PR. Accuracy doesn't change.&lt;/p&gt;




&lt;h3&gt;
  
  
  Making "internal" the safe default
&lt;/h3&gt;

&lt;p&gt;When the model is uncertain, you want it to classify as "internal" (filtered out) rather than incorrectly labeling noise as a feature. Explicit instruction in the prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If you're uncertain whether a PR is user-facing, classify it as "internal".
It's better to miss a minor change than to include irrelevant noise in the changelog.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single line eliminated most false positives.&lt;/p&gt;




&lt;h3&gt;
  
  
  Full context helps
&lt;/h3&gt;

&lt;p&gt;When available, include the linked issue title — not just the PR. Issues are usually written with user language ("users can't log in after token refresh") while PRs are written with technical language ("fix race condition in token refresh handler"). The issue title often contains the user-impact description you're trying to generate.&lt;/p&gt;




&lt;p&gt;I built this for &lt;a href="https://github.com/berat/releasehub" rel="noopener noreferrer"&gt;ReleaseHub&lt;/a&gt; — a CLI that generates release notes from merged PRs. The full classification prompt is &lt;a href="https://github.com/berat/releasehub/blob/main/packages/cli/src/lib/ai.ts" rel="noopener noreferrer"&gt;here&lt;/a&gt; if you want to see it in production context.&lt;/p&gt;

&lt;p&gt;What prompting patterns have worked for you in classification tasks?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>typescript</category>
      <category>github</category>
      <category>programming</category>
    </item>
    <item>
      <title>I built an open source CLI that writes release notes from your merged PRs</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Fri, 12 Jun 2026 16:16:37 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/i-built-an-open-source-cli-that-writes-release-notes-from-your-merged-prs-4284</link>
      <guid>https://dev.to/beratbozkurt0/i-built-an-open-source-cli-that-writes-release-notes-from-your-merged-prs-4284</guid>
      <description>&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;After every release, someone on the team has to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go through 30+ merged PRs&lt;/li&gt;
&lt;li&gt;Filter out the noise — dependency bumps, CI fixes, internal refactors&lt;/li&gt;
&lt;li&gt;Rewrite technical titles into something a non-engineer can understand&lt;/li&gt;
&lt;li&gt;Format it for GitHub, the changelog, and Slack separately&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That "someone" was usually me. And every time it felt like work that shouldn't exist — the information is already in the PRs.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;ReleaseHub&lt;/strong&gt; is an open source CLI that automates this entire flow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @releasehub/cli
releasehub auth login
releasehub ai add-key
releasehub generate &lt;span class="nt"&gt;--from&lt;/span&gt; v1.0.0 &lt;span class="nt"&gt;--to&lt;/span&gt; v1.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It fetches your merged PRs between two tags via GitHub API, reads the PR titles, bodies, and labels, classifies each one (feature / improvement / bugfix / breaking / internal), filters out the noise, rewrites the rest into plain language using AI, and outputs whichever format you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just use GitHub's built-in release notes?
&lt;/h2&gt;

&lt;p&gt;GitHub generates a PR list. That's useful, but it doesn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand that "fix token refresh race condition" means "users were getting logged out"&lt;/li&gt;
&lt;li&gt;Hide internal changes from customer-facing notes&lt;/li&gt;
&lt;li&gt;Write a Slack message for the team&lt;/li&gt;
&lt;li&gt;Produce a Keep a Changelog entry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ReleaseHub does all of that from a single command.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works under the hood
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GitHub OAuth device flow&lt;/strong&gt; — &lt;code&gt;releasehub auth login&lt;/code&gt; opens a browser, no manual token setup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PR ingestion&lt;/strong&gt; — fetches all merged PRs between two tags, including body and linked issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI classification&lt;/strong&gt; — sends PRs in batches of 20, each gets tagged as feature / improvement / bugfix / breaking / internal. For vague PR titles it reads the body and linked issues — when still uncertain, it errs toward "internal" and filters it out&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output generation&lt;/strong&gt; — three formats: &lt;code&gt;github-release&lt;/code&gt;, &lt;code&gt;changelog&lt;/code&gt;, &lt;code&gt;slack&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No server, no database. Just your terminal, your GitHub token, and your own AI key (Anthropic or OpenAI).&lt;/p&gt;

&lt;h2&gt;
  
  
  CI/CD integration
&lt;/h2&gt;

&lt;p&gt;There's a &lt;code&gt;--quiet&lt;/code&gt; flag for pipeline use and a &lt;code&gt;--publish&lt;/code&gt; flag to create the GitHub Release directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate release notes&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;npx @releasehub/cli generate \&lt;/span&gt;
      &lt;span class="s"&gt;--from ${{ steps.prev_tag.outputs.tag }} \&lt;/span&gt;
      &lt;span class="s"&gt;--to ${{ github.ref_name }} \&lt;/span&gt;
      &lt;span class="s"&gt;--format github-release \&lt;/span&gt;
      &lt;span class="s"&gt;--publish \&lt;/span&gt;
      &lt;span class="s"&gt;--quiet&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;RELEASEHUB_GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.RELEASEHUB_GITHUB_TOKEN }}&lt;/span&gt;
    &lt;span class="na"&gt;RELEASEHUB_ANTHROPIC_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.RELEASEHUB_ANTHROPIC_KEY }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The CLI is the foundation. The roadmap includes a cloud version with a UI, shared team history, and webhook support for automatic generation on every tag push.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/berat/releasehub" rel="noopener noreferrer"&gt;https://github.com/berat/releasehub&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href="https://berat.app/releasehub/docs" rel="noopener noreferrer"&gt;https://berat.app/releasehub/docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Curious how others handle release communication — do you write notes manually, or do you have something automated?&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>github</category>
      <category>ai</category>
      <category>cli</category>
    </item>
    <item>
      <title>My First Real App with Vibe Coding: From Idea to Launch (and Why I Built TabRush)</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Wed, 18 Feb 2026 01:45:12 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/my-first-real-app-with-vibe-coding-from-idea-to-launch-and-why-i-built-tabrush-igf</link>
      <guid>https://dev.to/beratbozkurt0/my-first-real-app-with-vibe-coding-from-idea-to-launch-and-why-i-built-tabrush-igf</guid>
      <description>&lt;p&gt;I shipped my first real app using a vibe coding workflow, and it changed how I think about building products.&lt;/p&gt;

&lt;p&gt;The app is &lt;a href="https://tabrush.app" rel="noopener noreferrer"&gt;TabRush&lt;/a&gt;: a lightweight ad marketplace where one Safari tab becomes a spotlight for a sponsor. It’s inspired by the simplicity of early internet ideas, but built for makers and startups who want fast visibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built this
&lt;/h2&gt;

&lt;p&gt;I kept asking myself a simple question:&lt;br&gt;
Can one high-attention placement outperform dozens of ignored ad slots?&lt;/p&gt;

&lt;p&gt;Most indie teams don’t just struggle with shipping features.&lt;br&gt;
They struggle with distribution.&lt;/p&gt;

&lt;p&gt;So I wanted to build something that is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;easy to understand in seconds,&lt;/li&gt;
&lt;li&gt;fast to use,&lt;/li&gt;
&lt;li&gt;and focused on visibility, not complexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My first vibe coding experience
&lt;/h2&gt;

&lt;p&gt;I had used AI-assisted workflows before, but this was the first time I used vibe coding from idea to launch prep.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What worked&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tight constraints in prompts&lt;/li&gt;
&lt;li&gt;Short iteration loops&lt;/li&gt;
&lt;li&gt;Fast UI/content experimentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What didn’t&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generic outputs when prompts were too broad&lt;/li&gt;
&lt;li&gt;Inconsistent product voice without clear writing guidelines&lt;/li&gt;
&lt;li&gt;“Fast code” that still needed human product judgment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Big lesson&lt;/strong&gt;: vibe coding gives speed, but clarity and taste still come from the founder.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the product evolved
&lt;/h2&gt;

&lt;p&gt;TabRush started as a fun concept and became a clearer product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one spotlight tab for the latest sponsor&lt;/li&gt;
&lt;li&gt;side tabs for previous sponsors&lt;/li&gt;
&lt;li&gt;increasing value as new spots are booked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That evolution happened through repeated feedback and build-in-public iterations.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned during launch prep
&lt;/h2&gt;

&lt;p&gt;The final 20% was not just coding.&lt;br&gt;
&lt;strong&gt;It was&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;positioning,&lt;/li&gt;
&lt;li&gt;messaging,&lt;/li&gt;
&lt;li&gt;trust signals,&lt;/li&gt;
&lt;li&gt;and making the value obvious in 5 seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Shipping fast is useful. Shipping clear is what converts.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you’re building with vibe coding
&lt;/h2&gt;

&lt;p&gt;*&lt;em&gt;My practical advice:&lt;br&gt;
*&lt;/em&gt;- Define constraints before writing prompts&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate product clarity before polishing visuals&lt;/li&gt;
&lt;li&gt;Treat copy as product, not decoration&lt;/li&gt;
&lt;li&gt;Use AI for speed, but keep decisions human&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re curious, the product I built is TabRush.&lt;/p&gt;

&lt;p&gt;It’s my first full launch using this workflow, and I’m sharing the process publicly as I keep improving it.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>vibecoding</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>My website is open-source w/Gatsby!</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Sat, 27 Mar 2021 20:53:22 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/my-website-is-open-source-w-gatsby-1p4n</link>
      <guid>https://dev.to/beratbozkurt0/my-website-is-open-source-w-gatsby-1p4n</guid>
      <description>&lt;p&gt;I build my homepage with &lt;a href="https://www.gatsbyjs.com/" rel="noopener noreferrer"&gt;gatsby&lt;/a&gt; (&lt;a href="https://www.gatsbyjs.com/starters/gatsbyjs/gatsby-starter-blog" rel="noopener noreferrer"&gt;starter-blog&lt;/a&gt;). The repository is source code for &lt;a href="https://beratbozkurt.net/" rel="noopener noreferrer"&gt;beratbozkurt.net&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Blog post with markdown&lt;/li&gt;
&lt;li&gt;Show your favorite projects&lt;/li&gt;
&lt;li&gt;Share your photos with flickr&lt;/li&gt;
&lt;li&gt;Dark mode&lt;/li&gt;
&lt;li&gt;Webmention.io support&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &amp;nbsp;Reach to repo
&lt;/h2&gt;

&lt;p&gt;You can reach the repo and more details on my repo. &lt;a href="https://github.com/berat/homepage" rel="noopener noreferrer"&gt;https://github.com/berat/homepage&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>blog</category>
    </item>
    <item>
      <title>Help! Ionic The back button works incorrectly after multiple clicks on the same tab.</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Tue, 06 Oct 2020 21:15:05 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/help-ionic-the-back-button-works-incorrectly-after-multiple-clicks-on-the-same-tab-59g5</link>
      <guid>https://dev.to/beratbozkurt0/help-ionic-the-back-button-works-incorrectly-after-multiple-clicks-on-the-same-tab-59g5</guid>
      <description>&lt;h1&gt;
  
  
  Bug Report
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Ionic version:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;[ ] &lt;strong&gt;4.x&lt;/strong&gt;&lt;br&gt;
[x] &lt;strong&gt;5.x&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current behavior:&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;I made a mobile application with ionic5 as react and simply used tabs. I accidentally pressed the tab I was in at that moment 2 times and when I click the Hardware back button on my Android phone, it redirected it to that tab again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expected behavior:&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;Shouldn't it don't be kept in memory when I click that tab again while in the tab I am in? Or when I click on that tab, I shouldn't do any redirection. How many times I click on that tab, I want to go to the tab I am in before that tab.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to reproduce:&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;I can't provide an example, but we can think like this.&lt;/p&gt;

&lt;p&gt;There are 3 tabs: Homepage, Search and Profile.&lt;br&gt;
First, I click on the search tab while on the homepage and go to that page.&lt;br&gt;
While on the search page, I click the search tab 1 or more times.&lt;br&gt;
When I press the back button on my Android phone, it redirects me back to the Search page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related code:&lt;/strong&gt;&lt;br&gt;
I use a structure like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;IonReactRouter&amp;gt;
  &amp;lt;IonTabs&amp;gt;
    &amp;lt;IonRouterOutlet&amp;gt;
      &amp;lt;Route path="/" render={() =&amp;gt; &amp;lt;Redirect to="/home" /&amp;gt;} exact/&amp;gt;
      &amp;lt;Route path="/search" component={SearchScreen} exact /&amp;gt;
      &amp;lt;Route path="/profile" exact component={ProfileScreen} /&amp;gt;
    &amp;lt;/IonRouterOutlet&amp;gt;
    &amp;lt;IonTabBar className="tab-bar-box" slot="bottom"&amp;gt;
      &amp;lt;IonTabButton
        className="tab-button"
        tab="tab1"
        href="/home"&amp;gt;
        &amp;lt;div className="tab-bar-item feed" /&amp;gt;
        &amp;lt;IonLabel&amp;gt;{strings.tabs.feed}&amp;lt;/IonLabel&amp;gt;
      &amp;lt;/IonTabButton&amp;gt;
      &amp;lt;IonTabButton
        className="tab-button"
        tab="tab4"
        href="/search"&amp;gt;
        &amp;lt;div className="tab-bar-item search" /&amp;gt;
        &amp;lt;IonLabel&amp;gt;{strings.tabs.search}&amp;lt;/IonLabel&amp;gt;
      &amp;lt;/IonTabButton&amp;gt;
      &amp;lt;IonTabButton
        className="tab-button"
        tab="tab5"
        href="/profile"&amp;gt;
        &amp;lt;div className="tab-bar-item profile" /&amp;gt;
        &amp;lt;IonLabel&amp;gt;{strings.tabs.profile}&amp;lt;/IonLabel&amp;gt;
      &amp;lt;/IonTabButton&amp;gt;
    &amp;lt;/IonTabBar&amp;gt;
  &amp;lt;/IonTabs&amp;gt;
&amp;lt;/IonReactRouter&amp;gt;
&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;insert short code snippets here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Other information:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ionic info:&lt;/strong&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ionic:

   Ionic CLI       : 6.11.10 (/Users/root/.config/yarn/global/node_modules/@ionic/cli)
   Ionic Framework : @ionic/react 5.1.1

Capacitor:

   Capacitor CLI   : 1.5.2
   @capacitor/core : 1.3.0

Utility:

   cordova-res : not installed
   native-run  : not installed

System:

   NodeJS : v14.12.0 (/usr/local/Cellar/node/14.12.0/bin/node)
   npm    : 6.14.8
   OS     : macOS Catalina
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ionic</category>
      <category>react</category>
    </item>
    <item>
      <title>A Nice Story of Experience and Failure…</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Sat, 03 Oct 2020 14:15:29 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/a-nice-story-of-experience-and-failure-5aph</link>
      <guid>https://dev.to/beratbozkurt0/a-nice-story-of-experience-and-failure-5aph</guid>
      <description>&lt;p&gt;I have launched to Davetiyem.co, digital wedding invitation creation project, on January 19, 2019. I have completed my project which has been active for about 2 years, as of September 27, 2019. I have won good experience and knowledge on this road I set out to gain experience and achieve something. I wanted to share a few thing to myself and share with you what I learned, what I did wrong during this project. &lt;/p&gt;



&lt;p&gt;Let’s start. But first if your age is 24 or above, please close the article without reading. Because I wanted to learn this things with yourself. Just do it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you are alone, you are nothing.&lt;/strong&gt;&lt;br&gt;
Okey, so nice. You have an idea and you believe that you will do it. You believe yourself and positive, it’s nice. Well who are with you? Who will you during this project with? Who are your workmates?&lt;/p&gt;

&lt;p&gt;I was alone in the project and this is one of my biggest problem. That’s why I had to do everything. In this way I couldn’t focus and productive in the project. Let’s think you work with 2 people. You are developer, one of your friends is designer and another is marketer. I think that is enough for a good work. As long as you distribute the task and everyone should work from the heart&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hit to market as soon as possible!&lt;/strong&gt;&lt;br&gt;
I tweeted at the time. But it’s Turkish.&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1290376689667776512-496" src="https://platform.twitter.com/embed/Tweet.html?id=1290376689667776512"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1290376689667776512-496');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1290376689667776512&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Really like this. Because you can do it the project somehow. Why do you think so much? Already nothing happens as you think it and when you launch the project you will change most of the things. Plan to implement your idean as simple and run. While you are already in the live, you will remove and add something. That’s why don’t think so much and don’t spend time with programming. Just do it!&lt;/p&gt;

&lt;p&gt;If you want, spent 5 or 6 months to programming the project. Is success guaranteed? Just launch the project and focus to keeping the user in app — be careful, I don’t say to win the user —&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Give importance to marketing!&lt;/strong&gt;&lt;br&gt;
I was the one who designed the project, interested in the programming side, managed social meda and blog site. But marketing… Marketing is different world for me. I could share with my circle but it was not enough. When you focus to marketing side, I think you can reach the user and keep the user in your app with a good strategy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Too hard without budget!&lt;/strong&gt;&lt;br&gt;
It happens to a level without budget, I cannot say to don’t happen. This level is just in first month. After a month, certain expenses must be made. Otherwise the app stays where it is and you will do just one think that how many people use and register to your app.&lt;/p&gt;




&lt;p&gt;The issues I’ve taken out of this process are generally like this. How about you to talk about what it gain me a little bit?&lt;br&gt;
The amount I earned financially from the project. I was just using adsense for blog site and recently I was getting a few click a day. Totally like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd1ad8yysrejdlw27dony.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd1ad8yysrejdlw27dony.png" alt="0_qXtQZLdyLbQObNqt" width="700" height="162"&gt;&lt;/a&gt;&lt;br&gt;
33.50 Turkish Lira = 4,37$ &lt;/p&gt;

&lt;p&gt;I switched the project to the paid version a few months ago. But it doesn’t work. Because anybody doesn’t register to site :) So I didn’t make money with paid version.&lt;/p&gt;

&lt;p&gt;I would like to excite you by writing financial gain here but unfortunately that’s all :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the same time I was applying to work a few company from Turkey and abroad as I was a student. When I said to “I have a startup”, this interview was getting more attention. I called it as a startup although it’s a small project. Then we were talking about the project and in this way they could understand me better. I think this approach makes me more efficient and hardworking. Because those of this ages (20) generally busy to consume something.&lt;/li&gt;
&lt;li&gt;I was trying to reach a lot of people for comment and feedback before and after launch the project. It’s really interesting because it’s truly world to be friend people with an entrepreneurial spirit. Because there are treat everything as both problem or resolve.&lt;/li&gt;
&lt;li&gt;When I was go to high school, I coding front side and I don’t know how to coding to back side. I was looking a few people for back end. I was start to meet a few people but I was left halfway. Therefore I learnt Python and then flask framework. I was finally able to write a back end service. It was amazing. You can imagine that this was a very difficult process. So I found myself somewhere I never expected. And I gained a different experience.&lt;/li&gt;
&lt;li&gt;I had very different trial and error that especially in technology and marketing. If you are a developer, whatever your field is I think you can focus on the field — of course if you are beginner level — . Because it is great investment for the future. By doing this, I can better determine my next step. Because I’ve experienced all this before.&lt;/li&gt;
&lt;li&gt;Like I said, I talked to a lot of people and heard their opinions. It means I reached new minds and that improve me. I learnt to design and programming, I think it’s very well:) I learnt how difficult the marketing process and which channels to use active. The essence of the word, I learnt very well :)&lt;/li&gt;
&lt;li&gt;Have we failed? Did not it work? Does it matter? We’ll try again. Our biggest gain from this is: We learned a good lesson and continue on our way to hit the target from 12.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1309756353053941760-626" src="https://platform.twitter.com/embed/Tweet.html?id=1309756353053941760"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1309756353053941760-626');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1309756353053941760&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Last thing I mean before I finish the article. Think, implement, improve, be happy! Nothing happens as you imagine. Nothing is that easy!&lt;/p&gt;

&lt;p&gt;The original: &lt;a href="https://medium.com/beratsblog/a-nice-story-of-experience-and-failure-a808edc154e0" rel="noopener noreferrer"&gt;Medium/beratsblog&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can reach me on &lt;a href="https://twitter.com/beratbozkurt0" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="http://instagram.com/beratbozkurt0" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;, &lt;a href="mailto:beratbozkurt1999@gmail.com"&gt;mail address&lt;/a&gt;. You can also go to &lt;a href="https://beratbozkurt.net/" rel="noopener noreferrer"&gt;my site&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>enterprise</category>
      <category>coding</category>
      <category>experience</category>
    </item>
    <item>
      <title>Building a Twitter Bot /w Node.js</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Tue, 22 Sep 2020 18:29:55 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/building-a-twitter-bot-w-node-js-50f3</link>
      <guid>https://dev.to/beratbozkurt0/building-a-twitter-bot-w-node-js-50f3</guid>
      <description>&lt;p&gt;I wanted build a bot about Twitter for avoid manually tweeting the keywords I want. Because this is a very demanding and time consuming task. Am I not a developer? Why don’t I programming a bot and it doesn’t do these things for me? And I was started :)&lt;/p&gt;




&lt;p&gt;We will use to 3 library for the bot.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Twit (&lt;a href="https://www.npmjs.com/package/twit" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/twit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;  Node-cron (&lt;a href="https://www.npmjs.com/package/node-cron" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/node-cron&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;  Express (&lt;a href="https://www.npmjs.com/package/express" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/express&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In fact only Twit library is enough, but I included Node-cron and Express libraries for I wanted it to work constantly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;npm init -y&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s create the project with the code above. Later, let’s install the libraries I mentioned the above to our project and keep going.&lt;/p&gt;

&lt;p&gt;Now we’re in the the twitter api creation section. I won’t explain this. Because you can find it on the google. This way you can create to API. Later create to api, let’s adding to config.js file on the project, and write to api keys and tokens here. File will be like this.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;don’t forget to change to the XXX’s&lt;/p&gt;

&lt;p&gt;Now, we will coding to the bot. For this, let’s import to install libraries and config file to our project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;const twiti = require(‘twit’);&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;const twit = new twiti(config);&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can connect the library as above.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;in  &lt;code&gt;params&lt;/code&gt;  object;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  q: I access tweets that contain the word I want.&lt;/li&gt;
&lt;li&gt;  count: I determine how many tweets I will access.&lt;/li&gt;
&lt;li&gt;  result_type: I determine what type of results are.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I determine that I have made the tweets I want by making a request to  &lt;code&gt;search/tweets&lt;/code&gt;  parameter with the twit.get function. There are also a few controls inside the function. If it passes these checks, I tweet and like.&lt;/p&gt;

&lt;p&gt;If I talk about the logic here, firstly I’m accessing tweets that I want and doing controls in function. The controls are about that not reply or not retweet and I’m checking to just send one reply to a tweet. If it’s okay, i’m reply and like to the tweet. Totally like this.&lt;/p&gt;




&lt;p&gt;Well, why are we using to express and node-cron libraries? I want the project to be running constantly on Heroku. For that reason, I built to web framework with express. I redirect to&lt;code&gt;/&lt;/code&gt;  and I used to node-cron to run it every 20 minutes. Because Twitter is blocking to the app for constantly tweeting and you don’t tweeting again. That’s why we put a 20-minute interval. Hereby the system works in 20 minute intervals.&lt;/p&gt;




&lt;p&gt;I also shared the project as open source.&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/berat/twitBot" rel="noopener noreferrer"&gt;https://github.com/berat/twitBot&lt;/a&gt;  (Don’t forget to start and follow :) )&lt;/p&gt;




&lt;p&gt;Original of the post: &lt;a href="https://medium.com/beratsblog/building-a-twitter-bot-w-node-js-80a88c25026a" rel="noopener noreferrer"&gt;https://medium.com/beratsblog/building-a-twitter-bot-w-node-js-80a88c25026a&lt;/a&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You can reach me on&lt;/em&gt; &lt;a href="https://twitter.com/beratbozkurt0" rel="noopener noreferrer"&gt;&lt;em&gt;my Twitter&lt;/em&gt;&lt;/a&gt;&lt;em&gt;,&lt;/em&gt; &lt;a href="https://twitter.com/beratbozkurt0" rel="noopener noreferrer"&gt;&lt;em&gt;Instagram&lt;/em&gt;&lt;/a&gt;&lt;em&gt;,&lt;/em&gt; &lt;a href="http://beratbozkurt1999@gmail.com/" rel="noopener noreferrer"&gt;&lt;em&gt;mail address&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. You can also go to&lt;/em&gt; &lt;a href="https://beratbozkurt.net/" rel="noopener noreferrer"&gt;&lt;em&gt;my site&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Word Box with React Native (Open Source)</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Sun, 05 Jul 2020 17:13:59 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/word-box-with-react-native-open-source-3ial</link>
      <guid>https://dev.to/beratbozkurt0/word-box-with-react-native-open-source-3ial</guid>
      <description>&lt;p&gt;I had been preparing a flashcard to learn English for a long time. To do these things faster, I made an application with react native and did not publish it anywhere. The project is not fully finished. But you can add and use words. So I wanted to put it up to this stage. If you want, you can continue developing.&lt;/p&gt;

&lt;p&gt;github: &lt;a href="https://github.com/berat/wordBox-react-native" rel="noopener noreferrer"&gt;https://github.com/berat/wordBox-react-native&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo (Video)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=nAQtdNFyuRg" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fj.gifs.com%2FGvJLZ7.gif" alt="Demo Video" width="800" height="400"&gt;&lt;/a&gt; &lt;br&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=nAQtdNFyuRg" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=nAQtdNFyuRg&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Screenshot
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fberat%2FwordBox-react-native%2Fmaster%2Fassets%2Fscreen1.png%3Ftoken%3DACQE2Z2HJ4RLPKB5U5PV3IC7BNA3M" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fberat%2FwordBox-react-native%2Fmaster%2Fassets%2Fscreen1.png%3Ftoken%3DACQE2Z2HJ4RLPKB5U5PV3IC7BNA3M" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fberat%2FwordBox-react-native%2Fmaster%2Fassets%2Fscreen2.png%3Ftoken%3DACQE2Z5H5TOEYUAAJSGB4US7BNA5G" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fberat%2FwordBox-react-native%2Fmaster%2Fassets%2Fscreen2.png%3Ftoken%3DACQE2Z5H5TOEYUAAJSGB4US7BNA5G" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fberat%2FwordBox-react-native%2Fmaster%2Fassets%2Fscreen3.png%3Ftoken%3DACQE2Z5NPCHSSNOS3ZQX6I27BNA6C" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fberat%2FwordBox-react-native%2Fmaster%2Fassets%2Fscreen3.png%3Ftoken%3DACQE2Z5NPCHSSNOS3ZQX6I27BNA6C" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Thank you for your watching
&lt;/h3&gt;

&lt;p&gt;To follow me &lt;a href="https://github.com/berat" rel="noopener noreferrer"&gt;Github&lt;/a&gt; - &lt;a href="https://twitter.com/beratbozkurt0" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; - &lt;a href="https://www.linkedin.com/in/beratbozkurt/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>I have a question for you, come here</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Mon, 15 Jun 2020 18:01:01 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/i-have-a-question-for-you-come-here-1f70</link>
      <guid>https://dev.to/beratbozkurt0/i-have-a-question-for-you-come-here-1f70</guid>
      <description>&lt;p&gt;Why should a person who wants to be a developer go to school for a few years? Actually not everyone can learn on their own? Can't they educate themselves?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Fortunately, I Am Developing The Project.</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Wed, 03 Jun 2020 11:41:26 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/fortunately-i-am-developing-the-project-5dcm</link>
      <guid>https://dev.to/beratbozkurt0/fortunately-i-am-developing-the-project-5dcm</guid>
      <description>&lt;p&gt;I have started to develop that I have been thinking about my own idea for 2 or 3 years. It took me a long time because I couldn’t spare time and didn’t know the technologies. Over time I have improved myself and spent time in time. Then I have developed the project. I only knew front-end. So I had to look for a friend to back-end. I had met a few people. Either we didn’t get along or he let me down. It didn’t seem like will be this kind of and I had started to learn of Python. I was thinking to develop my project by myself. Let look at the matter.&lt;/p&gt;

&lt;p&gt;In This Project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It helped me learn the programming language I wanted to learn.&lt;/li&gt;
&lt;li&gt;I developed a project after completing a training set.&lt;/li&gt;
&lt;li&gt;I improved my research skills.&lt;/li&gt;
&lt;li&gt;I improved a bit of my English.&lt;/li&gt;
&lt;li&gt;It guided me in human relations.&lt;/li&gt;
&lt;li&gt;It taught me to be patient.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Let’s go into details. I said I learned Python. I have finished the training set in 1 month. Then I started to develop Flask and My first project is this project. I did the project in about 3 months.&lt;/p&gt;

&lt;p&gt;I have searched a lot of things on google Because I didn’t know to use a lot of features in this project. These researches were taking sometimes 10 minutes, sometimes 3 hours, sometimes for days. I was taking a break when it lasted more than 3 days. Later I was continuing where I left off. So I understood how important it was to be patient. Turkish resources are insufficient. You are searching for English. I didn’t understand many articles in English and I was translating it into Turkish. Then I was trying to solve the problem.&lt;/p&gt;

&lt;p&gt;I was wondering what people thought of my project. I was writing to people for it. Some of them made positive feedback while others didn’t.&lt;/p&gt;

&lt;p&gt;That’s all that happened so far.&lt;/p&gt;

&lt;p&gt;Now There has marketing and social media business. Let’s see what happens then.&lt;/p&gt;




&lt;p&gt;If you have anything to ask, you can easily write to me without hesitating from my social media accounts.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can reach me on my &lt;a href="https://twitter.com/beratbozkurt0" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://twitter.com/beratbozkurt0" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;, &lt;a href="mailto:beratbozkurt1999@gmail.com"&gt;mail address&lt;/a&gt;. You can also go to &lt;a href="https://beratbozkurt.net" rel="noopener noreferrer"&gt;my site&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>React vs Vue: In My Opinion.</title>
      <dc:creator>Berat Bozkurt</dc:creator>
      <pubDate>Thu, 21 May 2020 15:13:50 +0000</pubDate>
      <link>https://dev.to/beratbozkurt0/react-vs-vue-in-my-opinion-32fh</link>
      <guid>https://dev.to/beratbozkurt0/react-vs-vue-in-my-opinion-32fh</guid>
      <description>&lt;p&gt;I’ve been trying to produce new projects with a lot of technologies in the front-end world for I currently continue my career as a freelancer. When I got a project, I aim to develop the project by choosing which technology is more reasonable to use. So I have to know about technologies and produce projects for practice.&lt;br&gt;
I normally develop projects with React and I’m actually very satisfied. I made a simple project with Vue when I hade some time. In this way, it was more than enough to understand the logic of Vue. I was wanting to write an article like this. So when I started learning React, I rewrote the application I wrote with React. It was going to easy to compare this way.&lt;br&gt;
&lt;/p&gt;

&lt;br&gt;
You can reach the repository and demo link below before start.&lt;br&gt;
&lt;strong&gt;React&lt;/strong&gt;&lt;br&gt;
Github Repository: &lt;a href="https://github.com/berat/react-practical" rel="noopener noreferrer"&gt;https://github.com/berat/react-practical&lt;/a&gt;&lt;br&gt;
Demo: &lt;a href="https://practical-react.herokuapp.com/" rel="noopener noreferrer"&gt;https://practical-react.herokuapp.com/&lt;/a&gt;

&lt;p&gt;&lt;strong&gt;Vue&lt;/strong&gt;&lt;br&gt;
Github Repository: &lt;a href="https://github.com/berat/vuejs-practical" rel="noopener noreferrer"&gt;https://github.com/berat/vuejs-practical&lt;/a&gt;&lt;br&gt;
Demo: &lt;a href="https://vuejs-practical.surge.sh/" rel="noopener noreferrer"&gt;https://vuejs-practical.surge.sh/&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;br&gt;
I would like to write in the form of titles but I don’t know much about term expressions. That’s why I’m writing as a ingredients.

&lt;ul&gt;
&lt;li&gt;I was easily develop the project with Vue for I was know React. It had a process so long for I started new everything when I started learning React. If you want to learn both React and Vue, I recommend starting with Vue. The Vue document is very successful at the beginning stage.&lt;/li&gt;
&lt;li&gt;I say React as the coding style. I don’t like to writing standard of Vue. It doesn’t work to write if, for in HTML for me.&lt;/li&gt;
&lt;li&gt;If you ask me that Redux or Vuex, no doubt I say Vuex. It’s really easy to deal with states in Vuex and You get immediate results. I guess I was spend 1–2 days to learn Redux.&lt;/li&gt;
&lt;li&gt;I can’t a choice for the Router. Both of them are basic and useful to me. So I passed this step.&lt;/li&gt;
&lt;li&gt;You use &lt;code&gt;&amp;lt;style&amp;gt;&amp;lt;script&amp;gt;&amp;lt;style&amp;gt;&lt;/code&gt; to build code structure in Vue. I don’t like to use situations (&lt;code&gt;v-if&lt;/code&gt;, &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;)that are just an option. I want be free when I write code. So Angular and Vue are the same, React is in a different place for me.&lt;/li&gt;
&lt;li&gt;I use Hooks on React. So It works Hooks for me. As far as I know, there are 5 or 6 lifecycles that are most used in Vue and it’s really easy and understandable to use them but if I have to make a choice I would vote on React’s side. —-I don’t know if there’s anything like Hooks in Vue--&lt;/li&gt;
&lt;li&gt;Vue devtool is better than React devtool. The designed the Vue devtool so nice that it’s very easy to use.

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you ask me which one to recommend, the only thing I will say to you. “Learn any of them and just get start”. It will be really easy to write the other once you start learning any of them. Then whichever makes more sense to you, you already use it. Choose both try side!&lt;/p&gt;

&lt;p&gt;There can be absolutely distinctive points but I just wanted to pass superficially. If I’m going to do a weekend project, I would definitely choose Vue. But I’m not surprised to use React in other projects.&lt;br&gt;
&lt;/p&gt;

&lt;br&gt;
I want to advertise before I finish the article :)&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1262588664053485568-860" src="https://platform.twitter.com/embed/Tweet.html?id=1262588664053485568"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1262588664053485568-860');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1262588664053485568&amp;amp;theme=dark"
  }



&lt;br&gt;
I would be glad if you could help me see everyone.&lt;br&gt;

&lt;br&gt;
If you have anything to ask, you can easily write to me without hesitating from my social media accounts.

&lt;blockquote&gt;
&lt;p&gt;You can reach me on my &lt;a href="https://twitter.com/beratbozkurt0" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://twitter.com/beratbozkurt0" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;, &lt;a href="mailto:beratbozkurt1999@gmail.com"&gt;mail address&lt;/a&gt;. You can also go to &lt;a href="https://beratbozkurt.net" rel="noopener noreferrer"&gt;my site&lt;/a&gt;.&lt;/p&gt;


&lt;/blockquote&gt;

</description>
      <category>react</category>
      <category>vue</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
