<?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: Justin Lam</title>
    <description>The latest articles on DEV Community by Justin Lam (@justinctlam).</description>
    <link>https://dev.to/justinctlam</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%2F26968%2F7f4c987b-1fc9-46db-b315-3b4e2b801eb2.jpeg</url>
      <title>DEV Community: Justin Lam</title>
      <link>https://dev.to/justinctlam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/justinctlam"/>
    <language>en</language>
    <item>
      <title>How to grow in your career: Hint, it's not about the tech.</title>
      <dc:creator>Justin Lam</dc:creator>
      <pubDate>Wed, 08 Jul 2020 18:07:17 +0000</pubDate>
      <link>https://dev.to/justinctlam/how-to-grow-in-your-career-hint-it-s-not-about-the-tech-5787</link>
      <guid>https://dev.to/justinctlam/how-to-grow-in-your-career-hint-it-s-not-about-the-tech-5787</guid>
      <description>&lt;p&gt;Here is my take on 7 things to grow in your software development career beyond getting better at the tech.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Learning to estimate and plan
&lt;/h1&gt;

&lt;p&gt;A way to leverage more value from yourself is to lead others to create value.  One way to lead others is to strengthen your estimation and planning skills.  Estimating how much work something takes is more of an art than science. What helps you get better at estimating is experience and technical knowledge.  Important and impactful projects take months with a team of developers. This will need coordination and organization to make sure you will deliver on time and on budget.  One reason why managers and leads are important because they can coordinate others.  Coordination is not easy but successful coordination can produce great value.  A senior developer should reinforce this skill.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Having an attitude to do more than expected
&lt;/h1&gt;

&lt;p&gt;In my career, I'm been guilty of refusing extra work before. I've once told a manager of mine that this isn't my responsibility. That kind of attitude held me back in my job.  You should be careful of limiting yourself to only what people ask of you. Be comfortable to venture beyond your job description.  This includes fixing those quality of life bugs that no one wants to bother. It could be improving internal tooling that has no clear ownership.  Don't be shy to volunteer for other things like helping onboard new hires or help with recruiting.  There might come a time when managers, PMs, or designers will need an extra hand. Offer to build a tool for them or assist them even if it doesn't involve coding. Rising beyond your expectation will definitely put you above the rest.  &lt;/p&gt;

&lt;h1&gt;
  
  
  3. Being able to convince others to follow your cause
&lt;/h1&gt;

&lt;p&gt;Going beyond senior demands the ability to convince others to follow your cause.  You'll need support from managers and colleagues if you want your ideas realized. Do you want to refactor major sections of the codebase? Do you want to launch that other amazing new feature? How about getting people to fix their bugs?  You should be able to communicate the benefits of your idea and why people should help you.  The goal is to get enough excitement that others will start championing for you.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Learning to read the room, maintaining professionalism
&lt;/h1&gt;

&lt;p&gt;One thing I've seen hold people back in their career is not controlling their emotions. Being able to project positivity that encourages peers is invaluable.  A senior developer should understand how to deliver critical feedback well.  Being condescending and negative can create an uncomfortable atmosphere to work in.  Growing more senior means learning how your actions and attitudes affect everyone else.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. High level of patiences
&lt;/h1&gt;

&lt;p&gt;Too many times have I seen mistakes happen because either I was too impatient or someone else was.  When you become impatient you will tend to say the wrong thing and choose the wrong decision. Over time, your career will test your patiences. There will be stress and there will be times of frustration. A high senior developer knows when to not rush and make good sounds decisions. Delaying work is much better than rushing for an immediate answer.&lt;/p&gt;

&lt;h1&gt;
  
  
  6. Perception means more than you think
&lt;/h1&gt;

&lt;p&gt;We all have an idea of what we are like. We know why we have decided to make a certain decision or done something a certain way. Yet, the internal model of yourself can be quite different from what others may think about you. How others think about you is actually more important than you think.  Managers and peers conduct performance reviews without you being in the room.  Facts about you are true or false but your soft skills are open to subjective interpretation.  This is why as you grow into a more senior level controlling your own public relations is something important to keep in mind. You may have done the work but are people seeing you as the person they would go to or someone else.  Your words and attitude can trump your technical skills so be aware of how you convey yourself.  &lt;/p&gt;

&lt;h1&gt;
  
  
  7. Mentoring not only junior people
&lt;/h1&gt;

&lt;p&gt;Developing yourself as a senior developer means to mentor junior and senior developers.  As you grow in your career take note of what you know and what others don't know. Junior developers will need mentorship but so do senior developers.  Think about what knowledge you posses that you can teach others. The approach might be different though. You can teach classes, hold retrospectives or write detailed documentation.  The idea is to think about how you can mentor or teach anyone you work with.&lt;/p&gt;

</description>
      <category>career</category>
      <category>development</category>
      <category>productivity</category>
      <category>skills</category>
    </item>
    <item>
      <title>Post Commit: Ensuring Quality Before Release</title>
      <dc:creator>Justin Lam</dc:creator>
      <pubDate>Tue, 23 Jun 2020 20:03:24 +0000</pubDate>
      <link>https://dev.to/justinctlam/post-commit-ensuring-quality-before-release-38dj</link>
      <guid>https://dev.to/justinctlam/post-commit-ensuring-quality-before-release-38dj</guid>
      <description>&lt;h1&gt;
  
  
  Story Time
&lt;/h1&gt;

&lt;p&gt;You just spent the last few weeks writing the latest and greatest feature for your users. You did your due diligence and wrote entire suite of unit tests and integration tests. Your fellow colleagues reviewed your code and gave their thumbs up. You press commit, your CI and CD processes are green and your feature officially releases. You go home eagerly anticipating the praises and accolades in the following days. &lt;/p&gt;

&lt;p&gt;Then it happens.&lt;/p&gt;

&lt;p&gt;The complaints start pouring in, tweets about how your new feature doesn't really work, even worst it broke other features in your app.  Things don't look good and you spend the next few days to a week fighting fires.  You are starting to lose customer satisfaction.  &lt;/p&gt;

&lt;p&gt;How would we have handled this better? I will describe how committing your feature is just the beginning of your journey to releasing your software.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's take a journey
&lt;/h1&gt;

&lt;h4&gt;
  
  
  Know What Success Means
&lt;/h4&gt;

&lt;p&gt;Hopefully before you begin writing your feature you know what success looks like and what metrics you are anticipating to move.  We don't build things in a vacuum, and new features don't automatically imply happy users. Are you looking for increase in new users, high engagement with existing users, better performance, etc... make sure you know what you want and how you will measure it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Have Internal Builds
&lt;/h4&gt;

&lt;p&gt;Some people might refer to this as an experimental build, sandbox build, alpha build, etc... This is a version of your build for internal use only.  The internal build allows developers to safely commit code for internal testing and experimentation. This is the build other engineers, PMs, designers, etc... will go to for an early feel of what the feature is going to do.&lt;/p&gt;

&lt;h4&gt;
  
  
  Dogfood Your Software
&lt;/h4&gt;

&lt;p&gt;Once you have an internal build deployment process, your next phase for ensuring quality is to have dogfooding sessions.  As the developer of your feature, setup some time with your team to test your new feature and do your best to break it. Report any bugs, fix, and repeat the dogfooding process a few times.  Also, this is a good time to evaluate design decisions, user interaction, performance, etc... &lt;/p&gt;

&lt;h4&gt;
  
  
  Formal QA Testing
&lt;/h4&gt;

&lt;p&gt;If your team is fortunate enough to have a QA team, this is the time to officially submit a build to them along with a write up on how to use it. Having dedicated QA professionals will help immensely in finding edge cases. The QA team should have additional resources, like multiple multiple devices or configurations to test on.  Examples include testing in many different screen sizes, all variations of mobile devices, different deployment environments, etc...&lt;/p&gt;

&lt;h4&gt;
  
  
  Use Feature Flags
&lt;/h4&gt;

&lt;p&gt;One of the best ways to save yourself in an emergency is to be able to turn your feature off after deployment.  Building feature flags into your code before release will give you that safety net.&lt;/p&gt;

&lt;h4&gt;
  
  
  Deploy Incrementally
&lt;/h4&gt;

&lt;p&gt;Internal dogfooding and QA testing can still miss some edge cases. Sometimes the best way to get feedback is from real users.  It is best to release your software incrementally. Start with 5% of your users and evaluate any feedback you might get back. Once things are stable, start deploying to 10%, 25%, 50%, 75%, etc... until you finally release to 100% of your users. Find a good cadence you feel necessary for your business. This helps ensure you don't upset too many users if something does go horribly wrong.&lt;/p&gt;

&lt;h4&gt;
  
  
  Measure Success Through Data
&lt;/h4&gt;

&lt;p&gt;Circling back to the first point, this is the time to measure if your feature is providing the value you intended.  This is also the time to make sure there aren't any performance issues and regressions through data. That means you need to have dashboards with metrics to monitor the health of your software. Don't always take anecdotes or customer feedback as your only source of feedback.  Sometimes the data will tell you a different story.&lt;/p&gt;

&lt;h1&gt;
  
  
  Release Is Only The Beginning
&lt;/h1&gt;

&lt;p&gt;Following these processes will help you release your software in a safe way.  But all the processes in the world won't guarantee 100% bug free and user satisfied software.  Keep an eye on your feature and continue to address any feedback and issues as they appear.  The success of your software really depends on the amount of love you give it through its life time after committing your code.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>testing</category>
      <category>career</category>
      <category>engineering</category>
    </item>
    <item>
      <title>Importance of Editing and Proofreading</title>
      <dc:creator>Justin Lam</dc:creator>
      <pubDate>Tue, 15 Jan 2019 14:37:16 +0000</pubDate>
      <link>https://dev.to/justinctlam/importance-of-editing-and-proofreading-fe5</link>
      <guid>https://dev.to/justinctlam/importance-of-editing-and-proofreading-fe5</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%2F8weafgazo8e3dseoacff.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%2F8weafgazo8e3dseoacff.jpg" alt="Proofreading Meme" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've experienced this time after time again, many developers don't proofread their work. I don't know why some developers have this urgency to submit their code for review right after they get it working without doing the important step of editing and proofreading.&lt;/p&gt;

&lt;p&gt;Do you remember in school when you finished that essay or research paper, you edited and proofread it before submitting right? I believe this should apply to our source code too.  In a way, source code is a developer's form of written communication. &lt;/p&gt;

&lt;p&gt;After you finished completing a portion of work that is ready for submission or code review, consider doing the following.&lt;/p&gt;

&lt;h2&gt;
  
  
  Editing:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Does your code integrate properly into the overall system. As an analogy, writing the next chapter in the book or the next paragraph in the essay.&lt;/li&gt;
&lt;li&gt;Using the right data structures for impact and efficiency.&lt;/li&gt;
&lt;li&gt;Are you expressing what you are doing clearly and to the point.&lt;/li&gt;
&lt;li&gt;Using the language as best as you can, e.g. don't write your Swift code like Java, or your JavaScript code like C#.&lt;/li&gt;
&lt;li&gt;Are you being overly verbose or too compact with your code.&lt;/li&gt;
&lt;li&gt;Have you communicated your intentions clearly that would be understood to another developer and not just the computer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Proofreading:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Have you checked for spelling, grammar, and typing mistakes. Linting helps but you'll be surprised how often people ignore lint warnings.&lt;/li&gt;
&lt;li&gt;Are you conforming to the style of the existing code and being careful of things that a linting tool might not catch.&lt;/li&gt;
&lt;li&gt;Did you go through a checklist of common runtime errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've heard reasons for not doing this, most of the time it comes down to "I want to submit my code as soon as possible. I don't want to be waiting around and have my code get out of date with the rest of the codebase." Our source code is not only how we make the computer work but also a form of communication between developers.  I encourage all developers, especially newer developers, to foster the same habit you have with other written communications. Edit and proofread your work before submitting.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>programming</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Time to change how we do Stand-Ups</title>
      <dc:creator>Justin Lam</dc:creator>
      <pubDate>Thu, 10 Jan 2019 12:40:46 +0000</pubDate>
      <link>https://dev.to/justinctlam/time-to-change-how-we-do-stand-ups-503</link>
      <guid>https://dev.to/justinctlam/time-to-change-how-we-do-stand-ups-503</guid>
      <description>&lt;p&gt;We are all familiar with the Stand-Up meeting, where everyone meets on a pre-determined cadence (every day, 3 times a week, etc...) to answer the 3 important questions. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What did I do yesterday that helped the development team meet the sprint goal?&lt;/li&gt;
&lt;li&gt;What will I do today to help the development team meet the sprint goal?&lt;/li&gt;
&lt;li&gt;Do I see any impediment that prevents me or the development team from meeting the sprint goal?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We call it the Stand-Up meeting because attendees are supposed to be standing while answering the 3 important questions. The discomfort of standing is intended to keep the meetings short. The reason we try to answer these 3 important questions is so that the project can be completed successfully in a timely matter.&lt;/p&gt;

&lt;p&gt;However, having worked in the software industry for many years and have been on countless teams I am feeling that we are severely abusing the original intent of Stand-Ups and just doing it "just because we have always been doing it".&lt;/p&gt;

&lt;p&gt;I have noted the following issues with the traditional in person Stand-Ups.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Absent attendees miss out on all the information presented.  This happens more often than you think. e.g. "I need to get my car fixed in the morning, will be missing stand up today", "Cat peed all over the carpet so I need to clean it up, will be missing stand up today", "Got a dentist appointment and will miss stand up today", etc...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;People are frequently late to Stand-Ups which inevitably prolongs the Stand-Up meeting time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;People almost always go off into tangent discussions that aren't important to the rest of the team. I am beginning to think this is just human nature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I've heard of other Stand-Ups lasting up to 45 minutes to an hour. That team felt quite proud of it too.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Forced time limit almost never works. Some people just love to describe every minute detail of their work even when the 3 minute timer is beeping.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Humans have terrible memory.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I want to propose we replace the face to face 15 minute Stand-Up meeting with group chat software (Microsoft Teams, Slack etc...).  This ensures the 3 important questions are documented and searchable.  No more missing information, no more he said/she said misunderstandings and threads can be replied to and referenced back.&lt;/p&gt;

&lt;p&gt;But I've heard feedback from teammates that they want to see each other face to face and they "supposedly" get value from making the Stand-Up meetings super long. Translation: We like to waste time talking about the weekend or what we did last night.  Well, may I introduce to you the "let's go get coffee together meeting" for those social needs.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>agile</category>
      <category>culture</category>
      <category>scrum</category>
    </item>
    <item>
      <title>Learn to defend your decisions</title>
      <dc:creator>Justin Lam</dc:creator>
      <pubDate>Wed, 13 Jun 2018 06:05:23 +0000</pubDate>
      <link>https://dev.to/justinctlam/learn-to-defend-your-decisions-1amk</link>
      <guid>https://dev.to/justinctlam/learn-to-defend-your-decisions-1amk</guid>
      <description>&lt;p&gt;One thing I learned recently which really helped me grow as an engineer is to learn how to defend my decisions.  When you make an choice on a framework to use, an architecture pattern, or the style of your code, it is very important that you can defend why you made that decision.  I have noticed that unseasoned or junior developers can't really justify why they made their choice. Typical answers when grilled includes, "That's how it's been done in other places in the codebase", "It works", "We have always been doing this", or "That's what everyone else does".&lt;/p&gt;

&lt;p&gt;How does being able to defend your action help you grow? For every decision you make while designing and developing, you should be asking yourself how would other people poke holes in my choice. If they do find a flaw, how would I be able to explain to them that it's okay or that I've thought about it and I've got a solution later.  A good developer will mostly likely be able to defend their decision with some hesitation if grilled on the spot.  An excellent developer would have already prototype the alternatives, vetted through any flaws well in advance and be able to defend their position when questioned.  You will grow tremendously when you do this. You will become more confident in your choices.  It's not easy and it takes a lot of time but it is rewarding. You might end up going down the rabbit hole that is full of tangential tracks but it will be worth it to your growth.&lt;/p&gt;

&lt;p&gt;There is a good technique you can use to help achieve more confidence in defending your decisions. When you make a choice you can try to ask your self why. Ask yourself why you are doing this, why is this better than the alternatives, why is it important, and keep asking why to drill down to the fundamentals.  Learn to be curious, learn to see alternatives, and learn to be humble.  You may have put in countless hours to learn every bit of defense for your decision but always be prepared to acknowledge you may not know everything and someone may provide a better solution.&lt;/p&gt;

&lt;p&gt;A note for those doing the grilling, be strict but be fair. There's no need to put others down if they can't completely defend their choice but use it as an opportunity for them to learn.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>World Block Creator</title>
      <dc:creator>Justin Lam</dc:creator>
      <pubDate>Sun, 20 May 2018 22:23:25 +0000</pubDate>
      <link>https://dev.to/justinctlam/world-block-creator-3b4p</link>
      <guid>https://dev.to/justinctlam/world-block-creator-3b4p</guid>
      <description>&lt;h1&gt;
  
  
  What I built
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0pe4mkgd797rn9y09fcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0pe4mkgd797rn9y09fcb.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This online web app allows you to build a 3D world using blocks.  While you are building your world, you can also see others build theirs in real time.  In addition, you can go into spectator mode and see all the creation happening around you. Get inspiration from others and build your own to showcase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo Link
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://worldblockcreator.herokuapp.com/" rel="noopener noreferrer"&gt;http://worldblockcreator.herokuapp.com/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Link to Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/justinctlam/WorldBlockCreator" rel="noopener noreferrer"&gt;https://github.com/justinctlam/WorldBlockCreator&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  How I built it
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Stack Overview:&lt;/strong&gt;&lt;br&gt;
Pusher - &lt;a href="https://pusher.com/" rel="noopener noreferrer"&gt;https://pusher.com/&lt;/a&gt;&lt;br&gt;
React - &lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;https://reactjs.org/&lt;/a&gt;&lt;br&gt;
Babylon.js - &lt;a href="http://www.babylonjs.com/" rel="noopener noreferrer"&gt;http://www.babylonjs.com/&lt;/a&gt;&lt;br&gt;
Heroku - &lt;a href="https://www.heroku.com" rel="noopener noreferrer"&gt;https://www.heroku.com&lt;/a&gt;&lt;br&gt;
TypeScript - &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;https://www.typescriptlang.org/&lt;/a&gt;&lt;br&gt;
Node.js - &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;https://nodejs.org/en/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Development&lt;/strong&gt;&lt;br&gt;
Being new to the web stack development world, I had to learn a lot about getting a simple web app standing from scratch. I knew I wanted to use TypeScript and Babylon.js as that is what I have been learning a lot about recently. &lt;/p&gt;

&lt;p&gt;My first step is to create a hello world client and server app and deploy it for use.  I struggled a bit in this area and most tutorials didn't give all the little details. Some tutorials are some combination of the stack I wanted but there was no one tutorial that met all my needs. However I did find one that I ended up using as the base of my application. &lt;a href="https://daveceddia.com/deploy-react-express-app-heroku/" rel="noopener noreferrer"&gt;Deploy React and Express to Heroku&lt;/a&gt; was the best one I found that taught me how to create a client and server app using React locally and how to deploy on Heroku for distribution. It worked wonders for me.&lt;/p&gt;

&lt;p&gt;I wanted to use TypeScript instead of JavaScript because I found the type checking really useful.  I decided to go with the &lt;a href="https://github.com/Microsoft/TypeScript-React-Starter" rel="noopener noreferrer"&gt;TypeScript-React-Starter&lt;/a&gt; kit from Microsoft. If you are following the tutorial from &lt;a href="https://daveceddia.com/deploy-react-express-app-heroku/" rel="noopener noreferrer"&gt;Deploy React and Express to Heroku&lt;/a&gt; you would make a simple change from &lt;code&gt;create-react-app client&lt;/code&gt; to &lt;code&gt;create-react-app client --scripts-version=react-scripts-ts&lt;/code&gt; to enable TypeScripting in the app.&lt;/p&gt;

&lt;p&gt;You can also add TypeScript support on the server side by adding the TypeScript package to the serve app. You can find an example on my GitHub.&lt;/p&gt;

&lt;p&gt;From here I've got a fully working app and server using React and TypeScript that is testable locally and deployable on Heroku!&lt;/p&gt;

&lt;p&gt;For my Pusher Contest idea I wanted to do something in 3D, so I decided to use Babylon.js as my 3D framework/engine package. I know Three.js is also very popular but I've been learning and using Babylon.js and is best to use what I am most efficient at the moment. I wanted to make something that users can create and share and I would use Pusher to allow you to see what others are building in real time.  &lt;/p&gt;

&lt;p&gt;The basic concept is simple. The user is presented a ground plane and when the user clicks on it, a small box appears where the user clicked on. The user can continue clicking on the plane or start clicking on the boxes and more boxes are placed where the user clicked. The user can also remove boxes by right clicking on them. From there the user can choose different colors for the boxes and start building whatever they can imagine.&lt;/p&gt;

&lt;p&gt;When the user decides to take a break, they are free to go into spectator mode and fly around looking at other users building their world in real time.  Be inspired by what others build and incorporate those designs into your own.&lt;/p&gt;

&lt;p&gt;For the real time aspect of the application I used Pusher channels for communication between the client and server. When a user does something on the client side, like adding a box or removing a box, an event is sent to the server. On the server side, those events are relayed to the other clients connected to the server.  Also on the server side, I used Pusher's webhooks to determine when a client is disconnected. Then the server will inform all the other clients about the disconnected client and the clients will remove the elements associated with the disconnected client from the 3D space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Future considerations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because of the limited time I can spend on this app, there are a few features I haven't implemented yet. I hope to get to them in the future:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store the data in a database to save between sessions&lt;/li&gt;
&lt;li&gt;Consider authentication to allow people to login&lt;/li&gt;
&lt;li&gt;Allow users to send likes about a design&lt;/li&gt;
&lt;li&gt;Add more tools or shapes to enable more expressive designs&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Additional Resources/Info
&lt;/h1&gt;

&lt;p&gt;I would love to hear about any feedback, bugs, or feature requests.&lt;/p&gt;

&lt;p&gt;To the Pusher Team, it would be nice to have TypeScript support for the server APIs.&lt;/p&gt;

</description>
      <category>pushercontest</category>
      <category>webdev</category>
      <category>node</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Reflections on GDC 2018</title>
      <dc:creator>Justin Lam</dc:creator>
      <pubDate>Wed, 28 Mar 2018 00:45:14 +0000</pubDate>
      <link>https://dev.to/justinctlam/reflections-on-gdc-2018-1pbo</link>
      <guid>https://dev.to/justinctlam/reflections-on-gdc-2018-1pbo</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I felt so blessed when my company gave me the opportunity to attend GDC aka Game Developers Conference. GDC is the world’s largest event for the professional game industry attracting the largest gathering of game developers in the world and I felt really amazing to be among all these talented individuals.  At this conference, professionals such as artists, engineers, and designers come together to showcase, discuss and present the latest technologies and learnings within the industry.  The conference format consists of workshops, summits, presentations, expo, and award ceremonies. &lt;/p&gt;

&lt;p&gt;GDC 2018 is my first ever GDC, and over the course of the five day conference I picked up a lot of knowledge, experience a lot of tech, and generally amazed at how much the game development industry has grown. I wanted to summarize a few interesting tidbits as well as offer suggestions on how to navigate GDC if you ever get a chance to go.&lt;/p&gt;

&lt;p&gt;Here is a quick high level view of GDC over the five day conference.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1522127896%2FCapture_jr6e28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1522127896%2FCapture_jr6e28.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are varying levels of passes you can purchase for the event where prices can range from $250 to $2300. Each type of pass provides increasingly more access to the events, for example the $250 Expo pass only allows you to visit the expo and awards ceremony while the $2300 All-access pass gives you the VRDC track, all of the GDC conference session, access to the online videos, and more.&lt;/p&gt;

&lt;h1&gt;
  
  
  VRDC
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1522129161%2FIMG_0176_yp4rob.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1522129161%2FIMG_0176_yp4rob.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was fortunate enough to get the all-access pass and I spent the first two days at the Virtual Reality Developers Conference, VRDC for short. At VRDC, I was able to get a good understanding of the latest developments in VR, AR, MR, and XR. In "Explorations in XR Creation Tools", I learned how Google built their new light panel in Tilt brush, how UnityLabs are exploring VR authoring within a VR environment and how Oculus designed their Home experience. There were good tips on prototyping with cardboard boxes from a session titled, "Playtesting VR: Brownboxing, Spycams, and Fuzzy Rugs". I also learned some good practices when building for multiple VR headsets in "1 Game, 6 Headsets, 10 Controllers: Multiplatform VR with 'Floor Plan'" and the importance of multi user collaboration experiences in "Room for Everyone: The 'Rec Room' Approach to Community VR" and "Pac-Man HoloLens: Developing a Mixed Reality Game for a Board Audience". In the session, "Exploring the Unsolved Challenges of VR Gaming", the speaker showed that VR still struggles with conveying weight, how to handle reading text, and locomotion. But despite these challenges, there were good presentations on best practices such as how to do gazing control in "Mind Control in Mobile VR: Gaze Activated in SingSpace".&lt;/p&gt;

&lt;h1&gt;
  
  
  GDC
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1522129161%2FIMG_0038_dx23h2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1522129161%2FIMG_0038_dx23h2.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GDC sessions offered up a variety of topics including engineering, art, design, and business. Many of the talks centered around the latest learnings from the past year within each discipline. &lt;/p&gt;

&lt;p&gt;As many of the presentations were recorded and will be posted on the GDC Vault online, I decided to attend the round tables session in lieu of the presentations. I found the round tables were some of the best things to attend and were considered quite unique as they were not recorded.  The round tables sessions gathered people to sit around a large table and talk about a topic, it can be about AI, animation, tools development, audio, business, etc. A wide range of experiences can be found at these round tables, from big influencers in the industry to first year students. The discussion is raw and eye opening because people speak from different perspectives and come from different walks in their journey in the industry. The hot topic this year seems to be if the game industry should unionize or not.&lt;/p&gt;

&lt;h1&gt;
  
  
  Expo
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1522129161%2FIMG_0247_k02g7i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1522129161%2FIMG_0247_k02g7i.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The GDC Expo is where companies from all around the world showcase their latest commercial products and latest technologies. You can find major companies, like Microsoft, Amazon, Google, Facebook, Unreal, Unity, Sony, etc. on the show floor creating excitement for their newest offerings.  The Microsoft booth was jam packed all three days, where you try out mixed reality headsets, Xbox demos and their new PlayFab backend infrastructure for multiplayer and telemetry services. Amazon also had a huge presence with their new GameOn service and Lumberyard game engine. Facebook was furiously demoing the new Oculus Go and Santa Cruz (mobile 6-dof HMD). Google had some daydream stuff.  Unity’s presence at GDC was huge, almost every mid to small size developers are using Unity and they have many performance enhancements coming, e.g., a new Entity Component System architecture, compiling C# to native code, and a new job scheduler system. Unreal and NVIDIA were showcasing their new real-time ray tracing technology. A few notable demos include, real time CGI human puppeteering, ultrasonic haptic feedback and full body VR equipment. &lt;/p&gt;

&lt;h1&gt;
  
  
  Getting the most of GDC
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1522129161%2FIMG_0241_yiopfl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1522129161%2FIMG_0241_yiopfl.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GDC is held at Moscone Center in downtown San Francisco.  San Francisco is a beautiful city but downtown San Francisco can be a bit sketchy.  Just watch yourself and stick to the crowds.&lt;/p&gt;

&lt;p&gt;As this is my first GDC, I always felt anxious about missing out on things because there was so much going on and so many sessions and events were overlapping. It is almost impossible to see everything so you need to make a plan but also allow yourself flexibility to change those plans. &lt;/p&gt;

&lt;p&gt;If I had to do it over again this would be my strategy.&lt;/p&gt;

&lt;p&gt;If you can afford it, definitely attend the VRDC talks or the tutorial sessions in the first two days.  They are an amazing experience. But don't fret if you can't because these session are recorded and are made available on the GDC Vault online. Although the GDC Vault is not cheap, estimated to be $550 if you don't have the right pass.&lt;/p&gt;

&lt;p&gt;Give yourself 2 hours each day to spend time at the Expo or more if you can afford the time.  See if you can find time slots in your schedule when none of the talks are interesting to you or if you think you can just watch later in the GDC Vault.  But be sure to attend the GDC Pitch days where participants practice pitching their games Shark Tank style. Super cool to watch.&lt;/p&gt;

&lt;p&gt;If you have a choice between going to a round table versus going to a talk, definitely attend the round tables.  While you are there, I encourage you to talk to people and don't be shy to speak up and participate in the discussions.  It's a very cool experience knowing you can bounce ideas back and forth with very senior people in the industry. Also make sure to attend the IGF and Game Developers choice awards ceremony as well.&lt;/p&gt;

&lt;p&gt;Finally, stay calm, drink lots of water, and keep snacks around. You will not have time to eat lunch : )&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Overall, GDC was an amazing experience. The atmosphere was electrifying.  You can sense the game development community is a tight knit group, who are very motivated in pursing their passion.  The awards ceremony during the middle of the conference revealed how much passion is in this industry. If I had to do it over again, I would bring business cards and spend a bit more time talking to individual people about their experiences and journey in the industry. I think the networking opportunities are abundant at conferences like these. I loved it and would want to go back again.&lt;/p&gt;

</description>
      <category>games</category>
      <category>conference</category>
      <category>ar</category>
      <category>vr</category>
    </item>
    <item>
      <title>Building a 3D application with Electron and BabylonJS using TypeScript</title>
      <dc:creator>Justin Lam</dc:creator>
      <pubDate>Tue, 26 Dec 2017 23:33:25 +0000</pubDate>
      <link>https://dev.to/justinctlam/building-a-3d-application-with-electron-and-babylonjs-using-typescript-2g29</link>
      <guid>https://dev.to/justinctlam/building-a-3d-application-with-electron-and-babylonjs-using-typescript-2g29</guid>
      <description>&lt;h1&gt;
  
  
  Table of Contents
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Setting Things Up&lt;/li&gt;
&lt;li&gt;Building the Application&lt;/li&gt;
&lt;li&gt;Time to Build&lt;/li&gt;
&lt;li&gt;Package and Distribute&lt;/li&gt;
&lt;li&gt;Final Thoughts and Resources&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/justinctlam/BabylonJS-Electron" rel="noopener noreferrer"&gt;https://github.com/justinctlam/BabylonJS-Electron&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;Are you interested in building a cross-platform desktop 3D application? Maybe you want to do a visualization application or even a game? I'm here to help, the following tutorial will guide you on setting up BabylonJS with Electron. I will also incorporate TypeScript so that you can see how all these technologies work together. I hope you find this combination useful and informative.&lt;/p&gt;

&lt;p&gt;I wrote this article to help me as well as others that are coming from a non-web background, maybe from iOS, Android, desktop application, backend, etc... I'll do my best to make this as straight forward as possible and I am targeting those who are just starting out with web development. &lt;/p&gt;

&lt;p&gt;First some basic explanation of the tech stack.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;BabylonJS&lt;/strong&gt;&lt;/em&gt;: A complete JavaScript framework for building 3D games with HTML5, WebGL, WebVR and Web Audio.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Electron&lt;/strong&gt;&lt;/em&gt;: Build cross platform desktop apps with JavaScript, HTML, and CSS.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/em&gt;: A free and open-source programming language developed and maintained by Microsoft. It is a strict syntactical superset of JavaScript, and adds optional static typing to the language. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To glue all this tech together I will be using the following infrastructure.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Visual Studio Code&lt;/strong&gt;&lt;/em&gt;: Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;NPM&lt;/strong&gt;&lt;/em&gt;: A package manager for JavaScript and the world’s largest software registry. Discover packages of reusable code — and assemble them in powerful new ways.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Electron-builder&lt;/strong&gt;&lt;/em&gt;: A Complete solution to package and build a ready for distribution Electron app with “auto update” support out of the box.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial will not assume you have anything already installed. I will cover all the tools that are necessary to build it from scratch. Let's begin!&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Setting Things Up
&lt;/h2&gt;

&lt;p&gt;Let's start by installing NodeJS which will give us the ability to use NPM. You can find it here (&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;https://nodejs.org/en/&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;This tutorial was tested on NodeJS version 6, which you can download here (&lt;a href="https://nodejs.org/dist/latest-v6.x/" rel="noopener noreferrer"&gt;https://nodejs.org/dist/latest-v6.x/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optional&lt;/strong&gt;: I would recommend using Visual Studio Code as your IDE. This is purely optional and not necessary to complete the tutorial. You can get VS Code here (&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;https://code.visualstudio.com/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Next, let's create a folder, let's call it &lt;code&gt;babylonjsElectron&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In a terminal or command prompt shell execute the following:&lt;/p&gt;

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

npm init


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

&lt;/div&gt;

&lt;p&gt;Select default for all options. This will create a &lt;code&gt;package.json&lt;/code&gt; for you with some parameters set.&lt;/p&gt;

&lt;p&gt;Next we will need to download and install some packages through NPM for our project. &lt;/p&gt;

&lt;p&gt;Execute the following commands in your terminal or command prompt.&lt;/p&gt;

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

npm install --save babylonjs@3.1.1
npm install --save-dev typescript@2.6.2
npm install --save-dev electron@1.7.10


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

&lt;/div&gt;

&lt;p&gt;From here onwards this tutorial will work with the following versions of the packages. &lt;strong&gt;3.1.1 of BabylonJS&lt;/strong&gt;, &lt;strong&gt;2.6.2 of TypeScript&lt;/strong&gt;, and &lt;strong&gt;1.7.9 of Electron&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A little bit of explanation about the package dependencies.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dependencies&lt;/code&gt; are the packages we will need to run our application and &lt;code&gt;devDependencies&lt;/code&gt; are packages we will use to help build the application but isn't required in the distribution of the application.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;package.json&lt;/code&gt; file should now contain these properties:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&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;span class="nl"&gt;"babylonjs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^3.1.1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&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;span class="nl"&gt;"typescript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.6.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"electron"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.7.9"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  3. Building the Application
&lt;/h2&gt;

&lt;p&gt;We'll need 3 files to start out &lt;code&gt;index.html&lt;/code&gt;, &lt;code&gt;main.ts&lt;/code&gt;, and &lt;code&gt;renderer.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;src&lt;/code&gt; folder under your current directory, for example &lt;code&gt;babylonjsElectron/src&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;src&lt;/code&gt; directory, create the two files &lt;code&gt;main.ts&lt;/code&gt; and &lt;code&gt;renderer.ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the root directory under &lt;code&gt;babylonjsElectron/&lt;/code&gt; create &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;main.ts&lt;/code&gt; put the following boiler plate code:&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;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BrowserWindow&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;electron&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;path&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;path&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;url&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;url&lt;/span&gt;&lt;span class="dl"&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;mainWindow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Electron&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BrowserWindow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createWindow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Create the browser window.&lt;/span&gt;
  &lt;span class="nx"&gt;mainWindow&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;BrowserWindow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// and load the index.html of the app.&lt;/span&gt;
  &lt;span class="nx"&gt;mainWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadURL&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;format&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&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="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;slashes&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="c1"&gt;// Open the DevTools.&lt;/span&gt;
  &lt;span class="nx"&gt;mainWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openDevTools&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Emitted when the window is closed.&lt;/span&gt;
  &lt;span class="nx"&gt;mainWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;closed&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="c1"&gt;// Dereference the window object, usually you would store windows&lt;/span&gt;
    &lt;span class="c1"&gt;// in an array if your app supports multi windows, this is the time&lt;/span&gt;
    &lt;span class="c1"&gt;// when you should delete the corresponding element.&lt;/span&gt;
    &lt;span class="nx"&gt;mainWindow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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="c1"&gt;// This method will be called when Electron has finished&lt;/span&gt;
&lt;span class="c1"&gt;// initialization and is ready to create browser windows.&lt;/span&gt;
&lt;span class="c1"&gt;// Some APIs can only be used after this event occurs.&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createWindow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Quit when all windows are closed.&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;window-all-closed&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="c1"&gt;// On OS X it is common for applications and their menu bar&lt;/span&gt;
  &lt;span class="c1"&gt;// to stay active until the user quits explicitly with Cmd + Q&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;darwin&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quit&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;activate&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="c1"&gt;// On OS X it"s common to re-create a window in the app when the&lt;/span&gt;
  &lt;span class="c1"&gt;// dock icon is clicked and there are no other windows open.&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;mainWindow&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;createWindow&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="c1"&gt;// In this file you can include the rest of your app"s specific main process&lt;/span&gt;
&lt;span class="c1"&gt;// code. You can also put them in separate files and require them here.&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In the &lt;code&gt;renderer.ts&lt;/code&gt; file put the following code:&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&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;babylonjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Renderer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_canvas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLCanvasElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_engine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_scene&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Scene&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;createScene&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLCanvasElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// This creates a basic Babylon Scene object (non-mesh)&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scene&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_scene&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// This creates and positions a free camera (non-mesh)&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FreeCamera&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;camera1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Vector3&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;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// This targets the camera to scene origin&lt;/span&gt;
        &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTarget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Vector3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Zero&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="c1"&gt;// This attaches the camera to the canvas&lt;/span&gt;
        &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attachControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&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="c1"&gt;// This creates a light, aiming 0,1,0 - to the sky (non-mesh)&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;light&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HemisphericLight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Vector3&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;1&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="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Default intensity is 1. Let's dim the light a small amount&lt;/span&gt;
        &lt;span class="nx"&gt;light&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intensity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Our built-in 'sphere' shape. Params: name, subdivs, size, scene&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sphere&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Mesh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CreateSphere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sphere1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Move the sphere upward 1/2 its height&lt;/span&gt;
        &lt;span class="nx"&gt;sphere&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Our built-in 'ground' shape. Params: name, width, depth, subdivs, scene&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ground&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Mesh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CreateGround&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ground1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLCanvasElement&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;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BABYLON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createScene&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nx"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;runRenderLoop&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderer&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;Renderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;render-canvas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLCanvasElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In the &lt;code&gt;index.html&lt;/code&gt; put the following in it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Babylon JS Electron App&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;#render-canvas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="py"&gt;touch-action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"render-canvas"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app/renderer.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  4. Time to Build
&lt;/h2&gt;

&lt;p&gt;We are going to build the application now.  Normally you don't need to build JavaScript files but for TypeScript there is a "build" step that takes the TypeScript files and transpiles them into JavaScript for consumption.&lt;/p&gt;

&lt;p&gt;To start off, we will need a &lt;code&gt;tsconfig.json&lt;/code&gt;. Create a &lt;code&gt;tsconfig.json&lt;/code&gt; under the &lt;code&gt;babylonjsElectron/&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Then put the following in &lt;code&gt;tsconfig.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&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;"compilerOptions"&lt;/span&gt;&lt;span class="p"&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;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commonjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"noImplicitAny"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sourceMap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"baseUrl"&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;"paths"&lt;/span&gt;&lt;span class="p"&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;span class="nl"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node_modules/*"&lt;/span&gt;&lt;span class="p"&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;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"include"&lt;/span&gt;&lt;span class="p"&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;span class="s2"&gt;"src/**/*"&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="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;The "include" property tells the TypeScript compiler where to look for the source files.  We will be outputting our JavaScript files under &lt;code&gt;babylonjsElectron/app&lt;/code&gt; folder as specified in the "outDir" property. We also have "sourceMap" set to true so that the debugger can find and put breakpoints in the TypeScript file. For more information about the other properties, you can find them here in this resource: &lt;a href="https://www.typescriptlang.org/docs/handbook/tsconfig-json.html" rel="noopener noreferrer"&gt;https://www.typescriptlang.org/docs/handbook/tsconfig-json.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next we will add some command line scripts to &lt;code&gt;package.json&lt;/code&gt;. These command line scripts are used to help use execute various commands or combination of commands.&lt;/p&gt;

&lt;p&gt;In package.json add the following under the "scripts" property:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"electron ./app/main.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt;So your &lt;code&gt;package.json&lt;/code&gt; file should look like the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&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;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"electron ./app/main.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;tsc&lt;/code&gt; in the "build" property is the TypeScript compiler.  In the "start" property, we will launch electron with our compiled TypeScript source, main.js.&lt;/p&gt;

&lt;p&gt;You maybe wondering, what about &lt;code&gt;renderer.ts&lt;/code&gt; file? It's not reference in &lt;code&gt;main.ts&lt;/code&gt; but it is reference in &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Electron has two processes, the main process and the render process. The main process is responsible for creating and managing BrowserWindow instances and various application events. The render process is responsible for running the user-interface of your app. You can find a more detail explanation here: &lt;a href="https://codeburst.io/deep-dive-into-electrons-main-and-renderer-processes-7a9599d5c9e2" rel="noopener noreferrer"&gt;https://codeburst.io/deep-dive-into-electrons-main-and-renderer-processes-7a9599d5c9e2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In your terminal or command prompt, execute the following command:&lt;/p&gt;

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

npm run build


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

&lt;/div&gt;

&lt;p&gt;This will "build" your TypeScript file. Next, execute the following command:&lt;/p&gt;

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

npm start


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

&lt;/div&gt;

&lt;p&gt;This will launch the electron application. Success!&lt;/p&gt;

&lt;p&gt;Running on Mac&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1513832521%2Fbjse01_z906gw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1513832521%2Fbjse01_z906gw.jpg" title="Success Electron BabylonJS App" alt="Success Electron BabylonJS App"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Running on Windows&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1514089894%2Fbjsewind_wtdb74.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1514089894%2Fbjsewind_wtdb74.jpg" title="Success Electron BabylonJS App" alt="Success Electron BabylonJS App"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may see a warning like the following in your terminal or command prompt:&lt;/p&gt;

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

Electron Helper[68582:2728327] Couldn't set selectedTextBackgroundColor from default ()


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

&lt;/div&gt;

&lt;p&gt;At the time of this tutorial, this is a bug in Chromium. I'm going to assume it will be fixed in future builds of Electron so let's not worry about it.&lt;/p&gt;

&lt;p&gt;As you can see, when you run the application that the development panel is opened. If you prefer the development panel not open automatically, comment out the following line in &lt;code&gt;main.ts&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mainWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openDevTools&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  5. Package and Distribute
&lt;/h2&gt;

&lt;p&gt;Alright! Now that we have a working application, let's get ready to package it up for distribution.&lt;/p&gt;

&lt;p&gt;For this task we will need the electron-builder NPM package to help us.&lt;/p&gt;

&lt;p&gt;Execute the following command in your terminal or command prompt:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm install --save-dev electron-builder@19.49.0


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

&lt;/div&gt;

&lt;p&gt;Next we'll add the following script to "scripts" in &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"dist"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt;So now &lt;code&gt;package.json&lt;/code&gt; will look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"This is a babylonjs electron sample"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./app/main.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&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;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"electron ./app/main.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dist"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt;Be sure that you have something in your "description" property as well. &lt;/p&gt;

&lt;p&gt;You will also want to make sure that the "main" property is pointing to the &lt;code&gt;main.js&lt;/code&gt; file as shown above.&lt;/p&gt;

&lt;p&gt;We are at the final stretch.&lt;/p&gt;

&lt;p&gt;Finally, execute the following command:&lt;/p&gt;

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

npm run dist


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

&lt;/div&gt;

&lt;p&gt;This will generate a DMG file for you on Mac.  You can find the file under &lt;code&gt;babylonjsElectron/dist&lt;/code&gt; folder. When you open up your DMG, it should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1514089894%2Fbjsedmg_ix2gle.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdu0yn38n5%2Fimage%2Fupload%2Fv1514089894%2Fbjsedmg_ix2gle.jpg" title="DMG Window" alt="DMG Window"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to make a Windows application just run the following in your Windows command prompt.&lt;/p&gt;

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

npm run dist


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

&lt;/div&gt;

&lt;p&gt;This will generate an exe file for you on Windows.  You can find the file under &lt;code&gt;babylonjsElectron/dist&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;You can customize a few options for each system as well.&lt;/p&gt;

&lt;p&gt;If you intend to release your app, you will need to code-sign your application. For the purpose of this tutorial I will not be covering this but you can find more details here: &lt;a href="https://www.electron.build/code-signing" rel="noopener noreferrer"&gt;https://www.electron.build/code-signing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On Mac, you can specify some options for the DMG generator.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;package.json&lt;/code&gt;, you can add the following options to the DMG property:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&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;span class="nl"&gt;"appId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yourappid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dmg"&lt;/span&gt;&lt;span class="p"&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;span class="nl"&gt;"contents"&lt;/span&gt;&lt;span class="p"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;240&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"link"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/Applications"&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="p"&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;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;Let's quickly discuss what some of these properties mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"appId" is where you would put your application ID if you ever plan to submit to a store like App Store.&lt;/li&gt;
&lt;li&gt;In contents, you can specify the variety of files and paths to appear within the DMG. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find more details of the properties here: &lt;a href="https://www.electron.build/configuration/dmg" rel="noopener noreferrer"&gt;https://www.electron.build/configuration/dmg&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On Windows, you can customize the type of installer to use.&lt;/p&gt;

&lt;p&gt;By default, electron-builder will build a "nsis" (Nullsoft Scriptable Install System) installer. There are various other installer options such as a "portable" installer which will produce an executable that just runs and doesn't install, and a "squirrel" installer that does one click package updates.&lt;/p&gt;

&lt;p&gt;For example, you can add these addition configuration properties to the 'package.json' file to create a no installer executable:&lt;/p&gt;

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

"build": {
    "appId": "yourappid",
    "win": {
      target: "portable"
    }
  }


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

&lt;/div&gt;

&lt;p&gt;You can find more details of the properties here:&lt;br&gt;
&lt;a href="https://www.electron.build/configuration/win" rel="noopener noreferrer"&gt;https://www.electron.build/configuration/win&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Final Thoughts and Resources
&lt;/h2&gt;

&lt;p&gt;It's pretty cool that one can easily develop cross platform applications using just JavaScript, HTML, and CSS. Now, not only can you create a cross platform application but you can create a cross platform 3D application for richer and immersive experiences.&lt;/p&gt;

&lt;p&gt;At of the time of this tutorial, Chromium supports WebVR but Electron has yet to use the latest version of Chromium.  I'm hoping that not too long from now Electron will support WebVR and we can start building cross platform VR applications!&lt;/p&gt;

&lt;p&gt;You can find the full source code here on GitHub: &lt;a href="https://github.com/justinctlam/BabylonJS-Electron" rel="noopener noreferrer"&gt;https://github.com/justinctlam/BabylonJS-Electron&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some resources I used to write this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BabylonJS - &lt;a href="https://www.babylonjs.com/" rel="noopener noreferrer"&gt;https://www.babylonjs.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Babylon.js Editor and Electron - &lt;a href="https://medium.com/babylon-js/babylon-js-editor-and-electron-706d6faf479b" rel="noopener noreferrer"&gt;https://medium.com/babylon-js/babylon-js-editor-and-electron-706d6faf479b&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Electronylon - &lt;a href="https://github.com/mmmeff/Electronylon" rel="noopener noreferrer"&gt;https://github.com/mmmeff/Electronylon&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Building a desktop application with Electron - &lt;a href="https://medium.com/developers-writing/building-a-desktop-application-with-electron-204203eeb658" rel="noopener noreferrer"&gt;https://medium.com/developers-writing/building-a-desktop-application-with-electron-204203eeb658&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A complete guide to packaging your Electron app - &lt;a href="https://medium.com/how-to-electron/a-complete-guide-to-packaging-your-electron-app-1bdc717d739f" rel="noopener noreferrer"&gt;https://medium.com/how-to-electron/a-complete-guide-to-packaging-your-electron-app-1bdc717d739f&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cross-platform Desktop JavaScript 3D Game Engine with NodeJS, Electron and BabylonJS - &lt;a href="http://grosan.co.uk/cross-platform-javascript-3d-game-engine-with-nodejs-electron-and-babylonjs/" rel="noopener noreferrer"&gt;http://grosan.co.uk/cross-platform-javascript-3d-game-engine-with-nodejs-electron-and-babylonjs/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>babylonjs</category>
      <category>electron</category>
      <category>3d</category>
    </item>
  </channel>
</rss>
