<?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: Rizky Haksono</title>
    <description>The latest articles on DEV Community by Rizky Haksono (@rizkyhaksono).</description>
    <link>https://dev.to/rizkyhaksono</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%2F954509%2Fd4164f00-f870-4e71-80bb-de8d88c93740.jpeg</url>
      <title>DEV Community: Rizky Haksono</title>
      <link>https://dev.to/rizkyhaksono</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rizkyhaksono"/>
    <language>en</language>
    <item>
      <title>Why Men Don't Need to Hold It In</title>
      <dc:creator>Rizky Haksono</dc:creator>
      <pubDate>Fri, 04 Apr 2025 08:26:49 +0000</pubDate>
      <link>https://dev.to/rizkyhaksono/why-men-cant-cry-491d</link>
      <guid>https://dev.to/rizkyhaksono/why-men-cant-cry-491d</guid>
      <description>&lt;p&gt;“Men don't cry” sounds like a small sentence. It is not. Repeated often enough, it teaches boys to translate sadness into silence and fear into anger—two emotions that are considered more acceptable than vulnerability.&lt;/p&gt;

&lt;p&gt;I do not think the problem is that men cannot cry. The problem is that many men learn there may be a social cost when they do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Emotion is not the opposite of strength
&lt;/h2&gt;

&lt;p&gt;Crying is one way the body responds to pain, grief, exhaustion, relief, or being overwhelmed. It does not tell us whether someone is capable, dependable, or resilient.&lt;/p&gt;

&lt;p&gt;Strength is not the absence of feeling. Sometimes it is the ability to name what is happening before it leaks out as withdrawal, irritability, or self-destruction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why silence becomes a habit
&lt;/h2&gt;

&lt;p&gt;A person may stay quiet because previous honesty was mocked, minimized, used against them, or met with an immediate attempt to “fix” them. After enough experiences like that, silence can feel safer.&lt;/p&gt;

&lt;p&gt;This is why simply telling someone to open up is not enough. Trust is built by what happens after they speak.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to make the conversation safer
&lt;/h2&gt;

&lt;p&gt;When a friend shares something difficult, I try to remember a few simple things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;listen before offering advice;&lt;/li&gt;
&lt;li&gt;do not turn vulnerability into a joke later;&lt;/li&gt;
&lt;li&gt;ask whether they want ideas or only someone to hear them;&lt;/li&gt;
&lt;li&gt;keep private things private;&lt;/li&gt;
&lt;li&gt;check in again after the moment has passed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this requires perfect words. Presence is often more useful than a speech.&lt;/p&gt;

&lt;h2&gt;
  
  
  Crying is not the only measure
&lt;/h2&gt;

&lt;p&gt;Not everyone processes emotion by crying, and nobody should be pressured to perform vulnerability. The goal is not to make every man cry. It is to make room for honest emotion without punishment.&lt;/p&gt;

&lt;p&gt;That might look like talking, writing, prayer, exercise, therapy, sitting quietly with someone, or finally admitting, “I am not doing well.”&lt;/p&gt;

&lt;h2&gt;
  
  
  When support needs to be professional
&lt;/h2&gt;

&lt;p&gt;Friends matter, but they cannot replace professional care. Persistent hopelessness, thoughts of self-harm, panic, or an inability to function deserve help from a qualified mental-health professional or local crisis service.&lt;/p&gt;

&lt;p&gt;Asking for that help is not failure. It is a practical response to pain.&lt;/p&gt;

&lt;h2&gt;
  
  
  A better sentence
&lt;/h2&gt;

&lt;p&gt;Instead of teaching men not to cry, we can teach them that emotions are information, vulnerability requires courage, and seeking support is part of taking responsibility for their lives.&lt;/p&gt;

&lt;p&gt;There is nothing weak about being human in public.&lt;/p&gt;

</description>
      <category>mentalhealth</category>
    </item>
    <item>
      <title>A Time Management System I Can Actually Stick To</title>
      <dc:creator>Rizky Haksono</dc:creator>
      <pubDate>Mon, 02 Dec 2024 17:22:26 +0000</pubDate>
      <link>https://dev.to/rizkyhaksono/heres-how-to-manage-your-own-time-efficiently-4158</link>
      <guid>https://dev.to/rizkyhaksono/heres-how-to-manage-your-own-time-efficiently-4158</guid>
      <description>&lt;p&gt;I have tried complicated productivity systems before. Most of them lasted a week. The problem was not the app or the method; it was that maintaining the system became another task.&lt;/p&gt;

&lt;p&gt;What works better for me is deliberately boring: one list, a small number of priorities, and protected blocks of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with capacity, not ambition
&lt;/h2&gt;

&lt;p&gt;At the beginning of the day I choose three outcomes at most:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;one task that moves the main project forward;&lt;/li&gt;
&lt;li&gt;one maintenance task;&lt;/li&gt;
&lt;li&gt;one small task I can finish when my energy is lower.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Everything else stays in the backlog. A long list may look productive, but it makes every item feel equally urgent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put work on the calendar
&lt;/h2&gt;

&lt;p&gt;A task list tells me &lt;em&gt;what&lt;/em&gt; matters. A calendar forces me to decide &lt;em&gt;when&lt;/em&gt; it can happen.&lt;/p&gt;

&lt;p&gt;I normally reserve a focused block for engineering work, then leave smaller windows for messages, reviews, and administration. I also leave empty space. A schedule with no margin breaks as soon as a meeting runs late or a bug takes longer than expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the next action obvious
&lt;/h2&gt;

&lt;p&gt;“Work on portfolio” is not a useful task. “Fix the mobile education layout and test it at 390px” is.&lt;/p&gt;

&lt;p&gt;When I stop working, I leave a short note describing the next action. That tiny habit reduces the time I spend reconstructing context the following day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a shutdown ritual
&lt;/h2&gt;

&lt;p&gt;At the end of the day I spend a few minutes on three questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What did I actually finish?&lt;/li&gt;
&lt;li&gt;What is blocked, and by whom or what?&lt;/li&gt;
&lt;li&gt;What should be the first action tomorrow?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I close the work session. Rest is not a reward for clearing an infinite list; it is part of being able to do good work again.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I stopped doing
&lt;/h2&gt;

&lt;p&gt;I no longer track every minute, maintain several overlapping to-do apps, or treat a missed plan as a personal failure. Estimates are guesses. The useful response is to adjust the plan, not to build a prettier spreadsheet around the miss.&lt;/p&gt;

&lt;h2&gt;
  
  
  The system in one sentence
&lt;/h2&gt;

&lt;p&gt;Choose less, schedule the important work, define the next physical action, and review what really happened.&lt;/p&gt;

&lt;p&gt;It is not a revolutionary system. That is exactly why I can keep using it.&lt;/p&gt;

</description>
      <category>management</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Elysia.js on Bun: A Practical First Look</title>
      <dc:creator>Rizky Haksono</dc:creator>
      <pubDate>Mon, 02 Dec 2024 17:19:42 +0000</pubDate>
      <link>https://dev.to/rizkyhaksono/quick-look-of-elysiajs-new-gen-of-backend-4555</link>
      <guid>https://dev.to/rizkyhaksono/quick-look-of-elysiajs-new-gen-of-backend-4555</guid>
      <description>&lt;p&gt;I first tried Elysia because I wanted to know whether Bun could make a small TypeScript API feel simpler, not because I needed another framework to collect.&lt;/p&gt;

&lt;p&gt;The short answer: the setup is genuinely quick, and the type inference is the interesting part. The longer answer is that a fast hello-world is not enough reason to move an existing backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the smallest useful API
&lt;/h2&gt;

&lt;p&gt;Create the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun create elysia app
&lt;span class="nb"&gt;cd &lt;/span&gt;app
bun dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A small route looks like this:&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;Elysia&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;t&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="s2"&gt;elysia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Elysia&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/health&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;ok&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="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/notes&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="nx"&gt;body&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;(),&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="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;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;String&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="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Listening on http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;port&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What I like here is that validation sits beside the route. The schema is useful at runtime, while TypeScript infers the body type for the handler. There is less distance between what the endpoint accepts and what the editor understands.&lt;/p&gt;

&lt;h2&gt;
  
  
  What felt good
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The initial project is small enough to read in one sitting.&lt;/li&gt;
&lt;li&gt;Route definitions are concise without hiding the HTTP model.&lt;/li&gt;
&lt;li&gt;Runtime validation and TypeScript inference work together.&lt;/li&gt;
&lt;li&gt;Bun starts the development server quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That combination makes Elysia pleasant for prototypes, internal services, and focused APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would check before using it at work
&lt;/h2&gt;

&lt;p&gt;A framework choice is more than request throughput. I would also check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;whether the libraries we need behave correctly on Bun;&lt;/li&gt;
&lt;li&gt;how the team will handle logging, tracing, migrations, and background jobs;&lt;/li&gt;
&lt;li&gt;whether deployment supports the runtime without special workarounds;&lt;/li&gt;
&lt;li&gt;how easy it will be for another engineer to maintain the service six months later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If an existing Express or Fastify service is stable, a benchmark alone would not persuade me to rewrite it. Migration risk is real, and mature ecosystems are valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  My current take
&lt;/h2&gt;

&lt;p&gt;Elysia is worth trying when Bun is already an acceptable runtime and end-to-end typing matters to the project. I would reach for it on a small new service before considering it for a large migration.&lt;/p&gt;

&lt;p&gt;The framework made a strong first impression because it removes ceremony. The next test is not another hello-world; it is building one complete service with a database, authentication, tests, observability, and deployment. That is where a backend framework earns its place.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>backend</category>
      <category>typescript</category>
      <category>restapi</category>
    </item>
    <item>
      <title>Docker, Explained Through the Problem It Solves</title>
      <dc:creator>Rizky Haksono</dc:creator>
      <pubDate>Mon, 02 Dec 2024 17:17:23 +0000</pubDate>
      <link>https://dev.to/rizkyhaksono/what-is-docker-and-how-is-it-works-282a</link>
      <guid>https://dev.to/rizkyhaksono/what-is-docker-and-how-is-it-works-282a</guid>
      <description>&lt;p&gt;The first useful thing Docker gave me was not “cloud-native architecture.” It was a boring promise: the application should behave the same way on another machine.&lt;/p&gt;

&lt;p&gt;Before containers, a setup could depend on the exact Node version, system packages, environment variables, or a database installed on one laptop. Docker makes those assumptions explicit and packages the application process with its runtime dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Image, container, and volume
&lt;/h2&gt;

&lt;p&gt;These three words explain most day-to-day Docker work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;image&lt;/strong&gt; is an immutable template built from a Dockerfile.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;container&lt;/strong&gt; is a running instance of that image.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;volume&lt;/strong&gt; stores data that should survive when a container is replaced.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A container is not a tiny virtual machine. Containers share the host kernel, which is one reason they usually start faster and use fewer resources than full VMs.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small Node example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:22-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;deps&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:22-alpine&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_ENV=production&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=deps /app/node_modules ./node_modules&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; node&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build and run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; notes-api &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 &lt;span class="nt"&gt;--env-file&lt;/span&gt; .env notes-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The port mapping exposes container port 3000 on the host. The environment file supplies configuration at runtime instead of baking secrets into the image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Docker helps
&lt;/h2&gt;

&lt;p&gt;Docker is useful when I need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reproducible local environments;&lt;/li&gt;
&lt;li&gt;isolated services such as Postgres or Redis;&lt;/li&gt;
&lt;li&gt;the same artifact in CI and deployment;&lt;/li&gt;
&lt;li&gt;an explicit record of system dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It does not automatically make an application scalable or secure. A large image is still large. A process running as root is still risky. A stateful service still needs backups.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few habits that prevent pain
&lt;/h2&gt;

&lt;p&gt;Use a &lt;code&gt;.dockerignore&lt;/code&gt; file, pin important base-image versions, run as a non-root user, keep secrets outside the image, and rebuild images instead of manually changing running containers.&lt;/p&gt;

&lt;p&gt;For local multi-service work, Compose is often enough:&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="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.env&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:17-alpine&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local-only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The mental model I keep
&lt;/h2&gt;

&lt;p&gt;Docker packages a process and its dependencies behind a repeatable boundary. That boundary is valuable, but it is not magic. You still need to understand networking, storage, configuration, and the application itself.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>containers</category>
    </item>
    <item>
      <title>Choosing SSR, ISR, or CSR in Modern Next.js</title>
      <dc:creator>Rizky Haksono</dc:creator>
      <pubDate>Mon, 02 Dec 2024 17:16:31 +0000</pubDate>
      <link>https://dev.to/rizkyhaksono/ssr-vs-isr-vs-csr-in-nextjs-3d2k</link>
      <guid>https://dev.to/rizkyhaksono/ssr-vs-isr-vs-csr-in-nextjs-3d2k</guid>
      <description>&lt;p&gt;The SSR/ISR/CSR comparison is useful, but the usual explanation often turns it into three competing page types. In modern Next.js, they are better understood as decisions about &lt;strong&gt;where data is fetched, when work happens, and what can be cached&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I use this question first: who needs the data, and how fresh must it be?&lt;/p&gt;

&lt;h2&gt;
  
  
  Server rendering for request-time data
&lt;/h2&gt;

&lt;p&gt;Render on the server when the response depends on the current request: authentication, cookies, headers, or data that must be fresh.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;AccountPage&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;account&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="s2"&gt;https://api.example.com/account&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;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no-store&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome, &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser receives useful HTML, but the server performs the work for each request. Use that freshness deliberately; do not disable caching everywhere by habit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cached server rendering and revalidation
&lt;/h2&gt;

&lt;p&gt;For documentation, product pages, or articles, the same result can often be shared between visitors and refreshed periodically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductPage&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;products&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="s2"&gt;https://api.example.com/products&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;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ProductList&lt;/span&gt; &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the modern equivalent of the problem ISR solves: serve cached output quickly, then revalidate it according to the application's freshness requirements. For content-driven updates, tag-based or on-demand revalidation can be clearer than an arbitrary timer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client-side fetching
&lt;/h2&gt;

&lt;p&gt;Fetch in the browser when the data belongs to an interaction after the page loads: autocomplete results, a live chart, or a user-triggered refresh.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useSWR&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;swr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&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;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;LiveStatus&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="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;isLoading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSWR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/status&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;refreshInterval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&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;isLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Checking status…&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&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;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSR is not automatically faster. It can mean sending an empty shell, downloading JavaScript, and making another request before the user sees the content.&lt;/p&gt;

&lt;h2&gt;
  
  
  The practical decision
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Need&lt;/th&gt;
&lt;th&gt;Start with&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Request-specific or uncached data&lt;/td&gt;
&lt;td&gt;Server rendering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shared content that changes occasionally&lt;/td&gt;
&lt;td&gt;Cached server rendering + revalidation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interaction-owned or continuously updating data&lt;/td&gt;
&lt;td&gt;Client fetching&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A single page can use all three. The product description may be cached, account pricing may render per request, and a stock indicator may update in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I default to
&lt;/h2&gt;

&lt;p&gt;I keep data and rendering on the server unless an interaction genuinely needs client state. Then I add the smallest client component around that interaction. This usually ships less JavaScript and makes the loading path easier to reason about.&lt;/p&gt;

&lt;p&gt;The useful question is not “Which acronym wins?” It is “What is the cheapest place to do this work while meeting the freshness and interaction requirements?”&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>SDLC in Practice: The Loop Behind Shipping Software</title>
      <dc:creator>Rizky Haksono</dc:creator>
      <pubDate>Tue, 03 Sep 2024 04:15:25 +0000</pubDate>
      <link>https://dev.to/rizkyhaksono/metode-sdlc-dalam-pengembangan-software-3oa1</link>
      <guid>https://dev.to/rizkyhaksono/metode-sdlc-dalam-pengembangan-software-3oa1</guid>
      <description>&lt;p&gt;I used to see the Software Development Life Cycle as a diagram for reports: requirements, design, implementation, testing, deployment, maintenance. Real projects rarely move through those boxes once in a perfect circle.&lt;/p&gt;

&lt;p&gt;The useful part of SDLC is not memorizing the phases. It is making sure the team answers the right questions before and after code is written.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Understand the problem
&lt;/h2&gt;

&lt;p&gt;Before discussing frameworks, clarify the user, the painful workflow, the expected outcome, and the constraints. “Build a dashboard” is a request. “Help an operator find failed jobs within two minutes” is a problem we can test.&lt;/p&gt;

&lt;p&gt;Useful output at this stage can be small: a short problem statement, acceptance criteria, open questions, and a list of risks.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Choose the smallest workable design
&lt;/h2&gt;

&lt;p&gt;Design includes more than UI. It covers data ownership, boundaries between services, failure behavior, security, and how the system will be observed.&lt;/p&gt;

&lt;p&gt;I prefer decisions that are easy to reverse. A short design note explaining &lt;em&gt;why&lt;/em&gt; is often more valuable than a complicated diagram with no trade-offs.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Build in reviewable slices
&lt;/h2&gt;

&lt;p&gt;Large changes hide risk. A vertical slice—a thin path from interface to data and back—gives the team something real to review early.&lt;/p&gt;

&lt;p&gt;A useful pull request should make its intent visible, keep unrelated cleanup separate, and include enough verification that another engineer can trust the change.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Test the behavior that matters
&lt;/h2&gt;

&lt;p&gt;Testing is not a phase saved for the end. The test strategy should follow the risk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unit tests for important rules;&lt;/li&gt;
&lt;li&gt;integration tests at system boundaries;&lt;/li&gt;
&lt;li&gt;end-to-end tests for critical user paths;&lt;/li&gt;
&lt;li&gt;manual checks for layout, accessibility, and unexpected interactions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A green test suite does not prove the product solves the original problem. Acceptance criteria still matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Release with a way back
&lt;/h2&gt;

&lt;p&gt;Deployment should answer three questions: how do we know it worked, how do we detect harm, and how do we reverse it?&lt;/p&gt;

&lt;p&gt;That may mean logs and metrics, a feature flag, a staged rollout, database migration safeguards, or a tested rollback command. The level of ceremony should match the cost of failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Learn from production
&lt;/h2&gt;

&lt;p&gt;Production feedback starts the next loop. Support questions, latency, errors, and user behavior reveal assumptions that planning could not.&lt;/p&gt;

&lt;p&gt;Maintenance is not the sad ending of development. It is where software spends most of its life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Waterfall or Agile?
&lt;/h2&gt;

&lt;p&gt;Waterfall can fit work with stable requirements and costly phase changes. Iterative methods fit uncertainty better because they shorten the distance between an assumption and feedback. Most teams use a mixture, whether or not their process document admits it.&lt;/p&gt;

&lt;h2&gt;
  
  
  My practical version of SDLC
&lt;/h2&gt;

&lt;p&gt;Define the outcome, expose the riskiest assumption early, ship a reviewable slice, verify it, observe it, and feed what you learn into the next decision.&lt;/p&gt;

&lt;p&gt;The lifecycle is valuable when it helps people think clearly. When it becomes paperwork detached from the product, the diagram has replaced the work.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>MBKM Batch 6: What I Learned Building Software at BIGIO</title>
      <dc:creator>Rizky Haksono</dc:creator>
      <pubDate>Mon, 02 Sep 2024 10:25:18 +0000</pubDate>
      <link>https://dev.to/rizkyhaksono/my-journey-in-bigioid-as-full-stack-developer-3ijc</link>
      <guid>https://dev.to/rizkyhaksono/my-journey-in-bigioid-as-full-stack-developer-3ijc</guid>
      <description>&lt;p&gt;MBKM Batch 6 gave me something coursework could not: six months of working inside a software team where incomplete requirements, unfamiliar code, and deadlines were normal parts of the job.&lt;/p&gt;

&lt;p&gt;In 2024 I joined PT Bejana Investidata Globalindo (BIGIO) as a full-stack developer intern. I arrived expecting to improve my coding. I left with a much better understanding of how engineers learn inside a real project.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first month: real-time communication
&lt;/h2&gt;

&lt;p&gt;My first assignment was to build an application using WebSocket communication with PostgreSQL for persistence. The technology was new enough to be uncomfortable, which made the task useful.&lt;/p&gt;

&lt;p&gt;The difficult part was not opening a socket. It was thinking about connection state, how data should be stored, and what the application should do when the happy path failed. That project taught me to look beyond a demo that merely works on my machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging a .NET project for the first time
&lt;/h2&gt;

&lt;p&gt;I later worked on an existing .NET codebase for Bio Farma's eCRF project. My task involved a bug related to patient status.&lt;/p&gt;

&lt;p&gt;I had not worked professionally with .NET before. Instead of trying to understand the entire system at once, I traced the affected flow, reproduced the issue, read the surrounding code, and narrowed the change. That process became more valuable than memorizing framework syntax.&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%2Fuploads%2Farticles%2Fmo3pb85k4hwzjpf2cpdp.jpeg" 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%2Fuploads%2Farticles%2Fmo3pb85k4hwzjpf2cpdp.jpeg" alt="Working with the team during the internship" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  React, Spring Boot, and a three-day feature
&lt;/h2&gt;

&lt;p&gt;In April I implemented a data-export feature in a React and Spring Boot application. Spring Boot felt verbose compared with the tools I knew, but the explicit structure also made responsibilities easier to locate once I understood the project.&lt;/p&gt;

&lt;p&gt;I completed the feature in three days. The useful lesson was not the speed itself; it was learning how to enter an unfamiliar stack, find the relevant path, and deliver a bounded change without pretending to know everything first.&lt;/p&gt;

&lt;h2&gt;
  
  
  The habits around the code
&lt;/h2&gt;

&lt;p&gt;Every Thursday the team held knowledge-sharing sessions. I also practiced LeetCode problems to improve how I broke down logic.&lt;/p&gt;

&lt;p&gt;In May, work on the Info Pangan Jakarta admin and user applications gave me a clearer view of code organization: folder boundaries, naming, and readable structure matter because code is read by a team, not only executed by a computer.&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%2Fuploads%2Farticles%2Fla0071zd369voglk1655.jpeg" 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%2Fuploads%2Farticles%2Fla0071zd369voglk1655.jpeg" alt="A moment from the BIGIO internship" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Life outside the office
&lt;/h2&gt;

&lt;p&gt;The internship was also six months of living and learning with other people. On weekends, friends and I explored Yogyakarta—cafés, street food, Malioboro, the hills to the south, and occasional trips outside the city.&lt;/p&gt;

&lt;p&gt;Those breaks were not separate from doing good work. They helped us reset, talk about things other than tickets, and return with more energy.&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%2Fuploads%2Farticles%2Fwhufzabhqg5cx7maa5af.jpeg" 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%2Fuploads%2Farticles%2Fwhufzabhqg5cx7maa5af.jpeg" alt="Exploring Yogyakarta with friends" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On June 21, 2024, we celebrated BIGIO's anniversary together. It was a simple gathering with nasi kuning, but it remains one of the moments that makes the internship feel personal rather than just another line on a résumé.&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%2Fuploads%2Farticles%2Fr6uw0hzrqil42t0abn7v.jpeg" 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%2Fuploads%2Farticles%2Fr6uw0hzrqil42t0abn7v.jpeg" alt="BIGIO anniversary gathering" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What stayed with me
&lt;/h2&gt;

&lt;p&gt;The internship improved my technical range—WebSocket, PostgreSQL, .NET, React, and Spring Boot—but the more durable lesson was how to work when the stack is unfamiliar.&lt;/p&gt;

&lt;p&gt;Reproduce the problem. Read before changing. Ask focused questions. Keep the scope clear. Share what you learn. Leave the code easier for the next person to understand.&lt;/p&gt;

&lt;p&gt;That is what I carried forward from MBKM Batch 6 and my time at BIGIO.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>internship</category>
      <category>development</category>
      <category>developer</category>
    </item>
  </channel>
</rss>
