<?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>Forem: Patrick Offei Danso</title>
    <description>The latest articles on Forem by Patrick Offei Danso (@kennydop).</description>
    <link>https://forem.com/kennydop</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F720906%2F170dbee8-ca77-4b5a-9863-a5188b3a4e77.jpg</url>
      <title>Forem: Patrick Offei Danso</title>
      <link>https://forem.com/kennydop</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kennydop"/>
    <language>en</language>
    <item>
      <title>Quick Prototyping</title>
      <dc:creator>Patrick Offei Danso</dc:creator>
      <pubDate>Thu, 01 Jan 2026 08:47:02 +0000</pubDate>
      <link>https://forem.com/kennydop/quick-prototyping-2pl3</link>
      <guid>https://forem.com/kennydop/quick-prototyping-2pl3</guid>
      <description>&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%2F5gcx8z8njzv52gsoqgr1.jpg" 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%2F5gcx8z8njzv52gsoqgr1.jpg" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I'm prototyping, my goal is simple: &lt;strong&gt;prove the idea works before I fall in love with it&lt;/strong&gt;.&lt;br&gt;
Not perfect code. Just enough to learn something.&lt;/p&gt;

&lt;p&gt;This is hard for me, especially because I enjoy clean design and solid architecture. Left unchecked, I'll spend hours on theme, spacing, naming, or edge cases no user will ever hit. Rapid prototyping is how I fight that instinct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with clarity
&lt;/h2&gt;

&lt;p&gt;Before I open an editor, I try to answer a few questions in plain language:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What problem am I solving?&lt;/li&gt;
&lt;li&gt;Who is this for?&lt;/li&gt;
&lt;li&gt;What is the one thing this app must do well?&lt;/li&gt;
&lt;li&gt;How do I get users?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I can't explain the product in one or two sentences, I'm not ready to build. Code won't save unclear thinking.&lt;/p&gt;

&lt;p&gt;I usually write a very small PRD. Just the goal, the main user flow, and how I'll know it's working. This alone prevents a lot of wasted effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the skeleton first
&lt;/h2&gt;

&lt;p&gt;I don't start by building features. I start by building &lt;strong&gt;structure&lt;/strong&gt;.&lt;br&gt;
That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;routing&lt;/li&gt;
&lt;li&gt;basic layout&lt;/li&gt;
&lt;li&gt;data flow&lt;/li&gt;
&lt;li&gt;folder structure&lt;/li&gt;
&lt;li&gt;naming conventions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No business logic or abstractions yet. This gives the project a backbone. Once that's in place, everything else moves faster and stays less chaotic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start from a bootstrapped template
&lt;/h2&gt;

&lt;p&gt;I rarely start from a blank project anymore.&lt;br&gt;
A good starter or template already has the boring parts done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;project structure&lt;/li&gt;
&lt;li&gt;auth or basic user model (even if unused)&lt;/li&gt;
&lt;li&gt;linting, formatting, env setup&lt;/li&gt;
&lt;li&gt;routing and layout&lt;/li&gt;
&lt;li&gt;basic config&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This saves hours on day one and reduces decision fatigue.&lt;/p&gt;

&lt;p&gt;The key is not to fight the template. Remove what you don't need, keep what helps, and move on. We are focused on speed, not elegance. If you're building fast, a slightly opinionated setup is better than endless setup freedom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a UI library. Always.
&lt;/h2&gt;

&lt;p&gt;I no longer debate this.&lt;br&gt;
Buttons, inputs, modals, tables, … I don't want to think about them. A good UI library removes hundreds of tiny decisions that add no value at the prototype stage.&lt;br&gt;
This doesn't mean your product will look generic forever. It just means you're not wasting time solving solved problems.&lt;/p&gt;

&lt;p&gt;I remind myself, "Users care about value, not whether my border radius is unique."&lt;/p&gt;

&lt;h2&gt;
  
  
  Fight the urge for pixel perfection
&lt;/h2&gt;

&lt;p&gt;This is where I struggle the most.&lt;br&gt;
I'll adjust spacing. Then colors. Then font weights. Then responsiveness. Suddenly, two hours are gone and nothing meaningful changed.&lt;br&gt;
So I now force a rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this blocking user understanding? Fix it.&lt;/li&gt;
&lt;li&gt;Is this cosmetic? Ignore it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pixel perfection comes after validation, not before.&lt;br&gt;
Design polish is a reward for proven demand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't build everything at once, structure for change
&lt;/h2&gt;

&lt;p&gt;I don't try to ship every possible future feature in version one. Instead, I structure the project so adding things later doesn't feel painful.&lt;br&gt;
That means I don't build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;plugin systems&lt;/li&gt;
&lt;li&gt;event buses&lt;/li&gt;
&lt;li&gt;heavy domain layers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keep boundaries clear between features&lt;/li&gt;
&lt;li&gt;name files and functions based on what they do, not what they might become&lt;/li&gt;
&lt;li&gt;keep functions small and replaceable&lt;/li&gt;
&lt;li&gt;avoid hard-coded assumptions that lock me into one flow&lt;/li&gt;
&lt;li&gt;isolate parts that may change (auth, payments, integrations)&lt;/li&gt;
&lt;li&gt;leave short comments where future extensions are obvious&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I want to be able to add new features, external services/providers, and even different tools without needing a rewrite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose what you already know
&lt;/h2&gt;

&lt;p&gt;This is underrated.&lt;br&gt;
Shiny tech is fun, but familiarity wins when speed matters. When I use tools I already understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I debug faster&lt;/li&gt;
&lt;li&gt;I write fewer bugs&lt;/li&gt;
&lt;li&gt;I make better decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can always rewrite. You can't get back wasted time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI actually helps me
&lt;/h2&gt;

&lt;p&gt;AI is not where I start. It's where I accelerate.&lt;br&gt;
Once the structure exists, AI becomes very useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;drafting PRDs&lt;/li&gt;
&lt;li&gt;refining flows&lt;/li&gt;
&lt;li&gt;generating boilerplate&lt;/li&gt;
&lt;li&gt;writing tests&lt;/li&gt;
&lt;li&gt;spotting bugs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But only if I have a clear workflow.&lt;br&gt;
An example flow that works for me:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use one tool to clarify the idea and specs&lt;/li&gt;
&lt;li&gt;Use a coding assistant to help implement parts faster&lt;/li&gt;
&lt;li&gt;Use a bug-focused tool to review and catch issues&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I also keep:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rules&lt;/li&gt;
&lt;li&gt;guidelines&lt;/li&gt;
&lt;li&gt;project context&lt;/li&gt;
&lt;li&gt;folder structure docs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes AI responses more accurate and less chaotic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation is leverage
&lt;/h2&gt;

&lt;p&gt;Light documentation saves heavy refactors.&lt;br&gt;
I usually keep:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a PRD&lt;/li&gt;
&lt;li&gt;a simple flow diagram&lt;/li&gt;
&lt;li&gt;a structure doc (folders, APIs, contracts)&lt;/li&gt;
&lt;li&gt;a list of assumptions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Validate early, then decide
&lt;/h2&gt;

&lt;p&gt;Once the prototype works end-to-end, I stop building.&lt;br&gt;
I put it in front of users. I watch them. I listen.&lt;br&gt;
Only after validation do I decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;polish UI&lt;/li&gt;
&lt;li&gt;refactor architecture&lt;/li&gt;
&lt;li&gt;add features&lt;/li&gt;
&lt;li&gt;or kill the idea&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fast prototyping isn't about being sloppy.&lt;br&gt;
It's about being &lt;strong&gt;honest with time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Build the smallest thing that can teach you something real.&lt;br&gt;
Everything else is noise.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>buildinpublic</category>
      <category>buildingwithai</category>
      <category>vibecoding</category>
    </item>
    <item>
      <title>How to Create an Executable .jar file for JavaFX using Maven</title>
      <dc:creator>Patrick Offei Danso</dc:creator>
      <pubDate>Sat, 02 Sep 2023 15:58:47 +0000</pubDate>
      <link>https://forem.com/kennydop/how-to-create-an-executable-jar-file-for-javafx-using-maven-3np2</link>
      <guid>https://forem.com/kennydop/how-to-create-an-executable-jar-file-for-javafx-using-maven-3np2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;You’re probably in a situation where you’ve written a great piece of software, tested it rigorously, and are now facing the daunting task of turning your masterpiece into something that can be executed with a double-click.&lt;/p&gt;

&lt;p&gt;When I first delved into this, I found myself stuck in a labyrinth of outdated tutorials, confusing stack overflow answers, and documentation that seemed like it was written for someone with years of experience in Java deployment. I was searching for a straightforward guide to creating an executable &lt;code&gt;.jar&lt;/code&gt; file and the journey was anything but simple.&lt;/p&gt;

&lt;p&gt;That’s why I decided to write this article, to save you the hours of headache that I had to go through. Whether you’re a beginner or someone who just needs a refresher, this step-by-step guide is for you.&lt;/p&gt;

&lt;p&gt;This tutorial will focus on using Java 11 or later, JavaFX, and Maven for dependency management.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;p&gt;Your JavaFX application can run from the command line or IDE, but nothing happens when you double-click or open the &lt;code&gt;.jar&lt;/code&gt; build.&lt;br&gt;
You are using Java Development Kit (JDK) 11 or later&lt;br&gt;
You are using Maven for dependency management.&lt;/p&gt;


&lt;h2&gt;
  
  
  Building the Executable .jar File
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Create a New ‘Main’ Class
&lt;/h3&gt;

&lt;p&gt;Before we delve into creating the executable &lt;code&gt;.jar&lt;/code&gt; file, you need to make a slight modification in your code structure. You’ll need to create a new class that will run the main function of your existing main class. This is particularly important for JavaFX applications.&lt;/p&gt;

&lt;p&gt;Here’s how you do it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Main.java&lt;/code&gt; (New Class)&lt;br&gt;
Create a new Java class in your project and name it Main. Add the following code to this class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package your.package.name;

public class Main {
 public static void main(String[] args) {
 App.main(args);
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class simply calls the main function of your existing App class.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App.java&lt;/code&gt; (Previous Main Class)&lt;br&gt;
In case you’re wondering, here’s what your existing App class might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package your.package.name;

import java.io.IOException;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;

/**
 * JavaFX App
 */
public class App extends Application {
  private static Scene scene;

  @Override
   public void init() {
   }

   @Override
   public void start(Stage stage) throws IOException {
   scene = new Scene(loadFXML("app"), 800, 600);
   scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
   stage.setScene(scene);
   stage.setTitle("My App");
   stage.show();
   }

   static void setRoot(String fxml) throws IOException {
     scene.setRoot(loadFXML(fxml));
   }

   private static Parent loadFXML(String fxml) throws IOException {
     FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
     return fxmlLoader.load();
   }

   public static void main(String[] args) {
     launch();
   }

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

&lt;/div&gt;



&lt;p&gt;With this new Main class in place, you’ve set the stage to create an executable &lt;code&gt;.jar&lt;/code&gt; file that will launch your JavaFX application.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Update Your Maven pom.xml File
&lt;/h3&gt;

&lt;p&gt;The next step is to include the Maven Shade Plugin in your pom.xml configuration file. This plugin is essential for packaging the artifact in an uber-jar, including its dependencies and resources, and thus makes it executable. Here’s how to do it:&lt;br&gt;
Open your pom.xml file and add the following code snippet for the Maven Shade Plugin:&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;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;maven-shade-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;LATEST VERSION HERE&amp;lt;/version&amp;gt;
    &amp;lt;executions&amp;gt;
      &amp;lt;execution&amp;gt;
        &amp;lt;phase&amp;gt;package&amp;lt;/phase&amp;gt;
        &amp;lt;goals&amp;gt;
          &amp;lt;goal&amp;gt;shade&amp;lt;/goal&amp;gt;
        &amp;lt;/goals&amp;gt;
        &amp;lt;configuration&amp;gt;
          &amp;lt;transformers&amp;gt;
            &amp;lt;transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"&amp;gt;
              &amp;lt;mainClass&amp;gt;your.package.name.Main&amp;lt;/mainClass&amp;gt;
            &amp;lt;/transformer&amp;gt;
          &amp;lt;/transformers&amp;gt;
        &amp;lt;/configuration&amp;gt;
      &amp;lt;/execution&amp;gt;
    &amp;lt;/executions&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure you replace &lt;code&gt;your.package.name.Main&lt;/code&gt; with the fully qualified name of your new Main class and &lt;code&gt;LATEST VERSION HERE&lt;/code&gt; with the latest version of the Maven Shade Plugin, for example: &lt;code&gt;3.5.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Your Final &lt;code&gt;pom.xml&lt;/code&gt; Should Look 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;!-- ... existing content ... --&amp;gt;
&amp;lt;build&amp;gt;
  &amp;lt;plugins&amp;gt;
    &amp;lt;!-- ... existing plugins ... --&amp;gt;
    &amp;lt;plugin&amp;gt;
      &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;maven-shade-plugin&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;3.5.0&amp;lt;/version&amp;gt;
      &amp;lt;executions&amp;gt;
        &amp;lt;execution&amp;gt;
          &amp;lt;phase&amp;gt;package&amp;lt;/phase&amp;gt;
          &amp;lt;goals&amp;gt;
            &amp;lt;goal&amp;gt;shade&amp;lt;/goal&amp;gt;
          &amp;lt;/goals&amp;gt;
          &amp;lt;configuration&amp;gt;
            &amp;lt;transformers&amp;gt;
              &amp;lt;transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"&amp;gt;
                &amp;lt;mainClass&amp;gt;com.example.Main&amp;lt;/mainClass&amp;gt;
              &amp;lt;/transformer&amp;gt;
            &amp;lt;/transformers&amp;gt;
          &amp;lt;/configuration&amp;gt;
        &amp;lt;/execution&amp;gt;
      &amp;lt;/executions&amp;gt;
    &amp;lt;/plugin&amp;gt;
  &amp;lt;/plugins&amp;gt;
&amp;lt;/build&amp;gt;
&amp;lt;!-- ... existing content ... --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Building and Testing the .jar File
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cleaning the Project:&lt;/strong&gt; Open your terminal and navigate to your project directory. Run the following command to clean any previous builds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mvn clean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Testing the New Main Class:&lt;/strong&gt; Before proceeding further, ensure that your new Main class can run the application correctly. You can do this by running your project from your IDE or using the Maven command &lt;code&gt;mvn javafx:run&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building the &lt;code&gt;.jar&lt;/code&gt; File:&lt;/strong&gt; If everything works as expected, go back to your terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mvn install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will compile your code, download any required dependencies, and package everything into a &lt;code&gt;.jar&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Locating the .jar Files:&lt;/strong&gt; After running &lt;code&gt;mvn install&lt;/code&gt;, you’ll find two &lt;code&gt;.jar&lt;/code&gt; files in the target directory of your project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;your-artifact-id-version.jar&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;your-artifact-id-version-shaded.jar&lt;/code&gt;
The second .jar file, which ends in &lt;code&gt;-shaded&lt;/code&gt;, is the one you’re interested in. This is the executable &lt;code&gt;.jar&lt;/code&gt; file that includes all your project’s dependencies.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now navigate to the target directory in your project folder and double-click the &lt;code&gt;.jar&lt;/code&gt; file that ends in &lt;code&gt;-shaded&lt;/code&gt;. Your JavaFX application should launch and run as expected, confirming that you’ve successfully created an executable &lt;code&gt;.jar&lt;/code&gt; file.&lt;/p&gt;




&lt;h2&gt;
  
  
  You Did It! 🎉**
&lt;/h2&gt;

&lt;p&gt;Congratulations, you’ve just built an executable &lt;code&gt;.jar&lt;/code&gt; file for your &lt;strong&gt;JavaFX&lt;/strong&gt; application! You can now distribute this &lt;code&gt;.jar&lt;/code&gt; file, allowing users to run your application with just a double-click — No technical fuss involved.&lt;br&gt;
For a step-by-step visual guide, you can also check out this helpful &lt;a href="https://youtu.be/EyYb0GmtEX4?si=sT38CKiJ-4yiwl0Q"&gt;YouTube video&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>vscode</category>
      <category>maven</category>
    </item>
  </channel>
</rss>
