Watch Now
Announcing the launch of Org-Native Agents.

Adding 3D libraries and physics engines to your React app with Tabnine

Posted on October 17th, 2024

Gone are the days of being content with static images and texts on a website. The people crave an experience. Companies such as Google, NVIDIA, and Time Warner are leveraging the 3D JavaScript framework Three.js to create interactive visualizations and high-quality 3D animations that run in the browser. Some creative developers, like Bruno Simon, have even gone as far as to turn their personal website into a fun game.

We recently welcomed Chris Good to our team as a Product Marketing Manager. Inspired by the work of Bruno Simon, Chris decided to use Tabnine to help him create a small Dinosaur Game (similar to the one built into Chrome) using Three.js and Cannon, a lightweight 3D physics for the web. Chris agreed to join me on an episode Tabnine Labs where we attempted to create a Plinko game and add it to an existing Remix application.

Check out the recording:

If you took the time to watch the recording, you’ll notice we had some struggles. We realized halfway through that we’d forgotten to use a physics engine. We were also introduced to React Three Fiber, which was required to render our Three.js graphics in React. This resulted in us being unable to finish our Plinko game before the end of the stream. With a little continued off-camera work, we were able to finish the game. You can view the code in this GitHub repo.

Tabnine was able to generate a good amount of the code based on our input, but there were some roadblocks. The following tips could help you avoid them.

Render on the client

Probably the biggest hurdle we encountered was actually getting React Three Fiber to render the game. The whole site refused to load and the errors we received weren’t helpful. After feeding Tabnine a lot of error messages and follow-up questions, we discovered that React Three Fiber must be rendered client-side. 

How to resolve this will differ based on the web framework you’re using. Because we were using Remix, all our pages were server-side rendered by default. With that in mind, we were able to help guide Tabnine to a solution that involved pulling game components out of the page component and making them client-side by renaming their files to .client.tsx. This removed them from the server bundle and forced them to be rendered on the browser.

Remember the third dimension

The other problem was our “flat” thinking. As the name suggests, Three.js is for creating 3D graphics but we were attempting to build our Plinko components as if they were two-dimensional. Discs were dropping straight through the pegs instead of colliding and bouncing. It wasn’t until we moved the camera, that we realized our components were at different Z positions resulting in them never touching. We weren’t using all the 3D shapes available to us; everything was a sphere or plane. It looked fine when viewed straight on, but caused a lot of confusion when things didn’t work. 

With this knowledge, we asked Tabnine to assist with converting pegs to cylinders and walls to boxes. Using these 3D shapes, it helped us align and size our components so they behaved appropriately in all three dimensions.

Leave the physics to the experts

During our first attempt, we forgot to use the physics engine. Can it be done without one? Sure. We found ourselves tweaking velocity formulas and calculating when items collide and how they should react to each other. Cannon handled that for us and Tabnine knew how to use Cannon. Unless you’re dying to dust off what you learned in that physics course you took long ago, just reach for a physics engine and focus your efforts elsewhere.

Could your website benefit from adding some 3D animations or interactions? Have Tabnine assist you in building something with Three.js —and let us know what you build. 

Not yet a Tabnine user? Sign up for a free 90-day Tabnine Pro trial.

Using Tabnine to build a CLI with Rust

Posted on October 10th, 2024

What do Prisma, Cloudflare, and Discord all have in common? Each of these companies uses the Rust programming language in production. From its creation in 2015, the low-level systems programming language has become beloved by developers from startups to large corporations, from embedded devices to scalable web services. Even Tabnine has selected Rust to help build the next generation of AI-powered software development tools.

Many command line interfaces (CLIs) have been written in Rust, so I decided to create one during an episode of Tabnine Labs. I set out to plan, create, and test a CLI that would display the current time and weather using the OpenWeather API for you and your coworkers. While I’m not completely new to programming in Rust, it was still nice to have Tabnine to assist me.

Check out the recording:

While we did technically end up with a CLI that met our specifications, the process didn’t go as smoothly as we had hoped. But have no fear, we learned a lot during the process and will share our course corrections and observations in this post.

Starting simple

When starting a new project that uses a language or libraries that are new to me, I like to begin by having a conversation with the chat. I ask questions to help me understand what I need to do and how to do it.

Here are some good questions to ask:

  • How would I create a CLI in Rust that does x? Please explain step-by-step.
  • What Rust crates are typically used in CLI projects?
  • What is the structure of a typical CLI written in Rust?

Using these questions, I created an initial CLI that used the OpenWeather API to display a current forecast for a city provided as an argument. Tabnine Chat guided me through creating a new cargo package that used the clap crate, a popular command line parser. Using the Tabnine Explain Agent helped me further familiarize myself with the generated code.

Before continuing on, I made sure the project was organized in the typical CLI project structure.

Using this structure allowed for a clean separation of concerns, making it easier to maintain and extend the CLI application as it grows. Doing this early cuts down on possible code refactoring later on and makes testing more straightforward.

The next change I made to this initial CLI was to include displaying the current time for the provided city. I expect this to be more of a challenge because working with time can be a nightmare. Many times you have to figure out time zones and do a lot of complicated time conversions that aren’t always straightforward. (Not so fun fact: Indian Standard Time [IST] is offset by half an hour, UTC+05:30.) With all this swirling in my head, I asked Tabnine Chat to also display the current time in the response. To my surprise, it knew that the location’s timezone was returned by the OpenWeather API and used it to calculate and display the time.

We’re off to a good start, but we’re only getting information for one city and we have to specify it each time.

Prompting for and persisting data

Most people work from the same location every day. We don’t want to force our users to specify a city every time they run our CLI. Many CLIs persist data using a config file stored in the user’s home directory. We’ll do the same to persist our data. There are a lot of different requirements when selecting, loading, and writing a config file, depending on the operating system and other environment factors. So before running off and trying to build your own, it’s a good idea to ask Tabnine Chat, “Are there any Rust crates that can help with managing and retrieving user-specific configuration data?” This is how I learned about the confy crate and how to add it to the project.

Now we can simply ask Tabnine chat to update our command to read the user’s city from a config file using comfy if one isn’t provided and to prompt the user for a city and store it in the config file if not available.

Adding subcommands

It’s time to include coworkers. To help with this, we’re going to use subcommands. The clap crate supports this out of the box. We’ll start by telling Tabnine the definition of a coworker and then ask it to explain step-by-step how to store a list of coworkers in the config and create subcommands to add, remove, and list them. Tabnine will respond with instructions on updating the config and how to add the subcommands in the commands folder.

Next, we’ll use Tabnine to help us update our print weather function to also display the current forecast and time for each coworker (if any exist) by asking in the chat.

Unit testing

Now that we have our basic functionality working, it’s a good time to start unit testing. By default, executing “cargo test” will run tests located in the tests folder of the project. If you’re unfamiliar with how testing works in Rust, I recommend asking Tabnine Chat, “How do I unit test this project?” It will help you get started with some basic tests.

Once you have basic testing set up, you can use the Tabnine Test Agent to generate additional unit tests to cover your functions. Do this by clicking the Test Agent icon in the chat window, selecting a function, and then clicking Generate test plan for code.

We were able to build this simple CLI quickly thanks to Tabnine. We didn’t need to look up how to make a request to the OpenWeather API or what values were returned. We were able to leverage popular crates without having to read pages of documentation.

There’s still so much that could be done, what if we need to update the user’s city? Can we make the output a little prettier? Just ask Tabnine Chat. What would you do next?

Are you building a CLI or some other application using Rust? Let us know how Tabnine is helping you. Not yet a Tabnine user? Sign up for a free 90-day trial of Tabnine Pro.

Introducing a new O’Reilly Guide: “The AI-Enabled SDLC”

Posted on October 8th, 2024

Get free early access to the upcoming O’Reilly Guide, The AI-Enabled SDLC: A Tech Leader’s Guide to Navigating the Future of Software Development.

Every company, no matter its size or sector, strives to produce high-quality software at the lowest cost and in the shortest time possible. To achieve this, technical teams have traditionally used a software development life cycle (SDLC) process — a well-structured flow of phases that enable the design and delivery of first-class software that is well tested and ready for production. 

Now, AI is transforming the traditional SDLC. Taking optimum advantage of the powerful capabilities that AI unlocks in each phase of the SDLC (as well as competing effectively) means that today’s development teams need to learn new tools and techniques. But what are these, exactly, and what is the best way to adopt AI tools into your software development pipeline?

An upcoming new book from Tabnine founder Eran Yahav and co-author Brent Laster will offer answers to these critical questions. The AI-Enabled SDLC: A Tech Leader’s Guide to Navigating the Future of Software Development, to be published early in 2025 by O’Reilly Media, will help engineering leaders and hands-on engineers alike understand how AI tools can improve each stage of their SDLC. The book will offer pragmatic guidance for technical leaders on how you can adapt their current software development processes, adopt AI-enabled software development tools, and enable your teams to be successful with AI tools. It will also be a valuable reference as you apply your newly gained knowledge in revising how your teams work and the tools they use.

The AI-Enabled SDLC uses the SDLC’s seven core stages (plan, create, test, fix, document, explain, and maintain) as the framework to examine and explain how the adoption and use of AI is fundamentally reshaping each one:

  • Plan: How AI tools can now be used to answer general coding questions, better understand the code in an existing project, or get solutions and references relevant to your organization’s codebase
  • Create: How developers can use natural language to generate code based on design specifications or requirements, teaching how to create software components, features, functionality, and more
  • Test: How AI coding assistants automate the generation of unit tests, including how AI tools are used to create tests for a specific function or code in your project, and get back test cases, implementation, and assertion
  • Fix: How identifying issues changes significantly when using AI tools for code reviews, showing how developers can select code with an error and have an AI coding assistant recommend fixes (including identification of security and performance issues along with recommendations for resolution) 
  • Document: How to improve your code and project docs by using AI to create documentation (including formal documentation of classes and functions for API guides, comments, and inline docs), while enhancing code readability to make it easier to understand and maintain in the future
  • Explain: How AI tools make project onboarding and code explanation dramatically easier, demonstrating how AI tools can explain an entire software project, snippets of legacy code from another developer, or help a developer understand code written in a language they’re unfamiliar with
  • Maintain: Covers how AI software tools change code refactoring and updates, illustrating how to use natural language to add functionality or refactor existing code, and specialty tools used to translate code from one language to another (e.g., COBOL to Java) 

Rather than waiting until the entire book is ready for publication, the authors are using a rapid release approach to make this information available as quickly as possible. The first three chapters of The AI-Enabled SDLC: A Tech Leader’s Guide to Navigating the Future of Software Development are now available, and Tabnine will be releasing updates to the guide as each chapter becomes available.

Downloading the first three chapters gives early readers a head start on understanding the role of LLMs in software development. Here’s what the initial set of chapters explores:

  • Exactly where AI is being adopted into the seven phases of the SDLC, and how it is used in each one
  • The crucial differences between general-purpose LLMs and purpose-built AI coding assistants 
  • Protecting code quality as velocity increases 
  • Planning new software development with AI assistance

Subsequent chapters build upon this knowledge to cover things the software industry has never before needed to consider: simplifying code translation (e.g., COBOL to Java) with AI tools; code creation and new feature development using natural language; and optimizing an AI tool’s context awareness to ensure it returns the highest quality recommendations.

Join this learning curve at the earliest possible point by downloading the first three chapters — and then stay ahead by signing up to receive new chapters as soon as they become available.

Building a Chrome extension with Tabnine

Posted on October 4th, 2024

I think it’s safe to say that if you use Google Chrome as your browser, you’ve likely used a Chrome extension, whether to help find a coupon to save 10% on a purchase, save a password, or for a variety of other reasons. What you might not know is that it’s pretty straightforward to create one yourself if you have some understanding of HTML and JavaScript. I decided to see how far I could get creating my first extension armed only with an idea, Tabnine, and two hours on a livestream. During this Tabnine Labs, I built a Chrome extension that would generate a strong password from scratch. Here’s the recording.

Let’s recap the ways Tabnine played a role in taking the extension from an idea to code.

Planning the extension

Because this was my first time creating a Chrome extension, I had no idea where to begin. Previously, I would’ve started with some Google searches, looked at example code, and possibly gone through some tutorial, but I didn’t have that kind of time. 

Instead, I did my research in a different way. I simply asked Tabnine Chat how to build a Chrome extension as if it were a seasoned Chrome extension developer. It told me step-by-step how to build it using plain HTML and JavaScript. This was enough information to get me thinking about how I wanted my solution to work. 

I wanted to use React and TypeScript to build the extension. Since the Tabnine Chat conversation is used as context, I continued by asking if I could use React and TypeScript. This presented me with a refined solution. I then noticed that it wanted to use Webpack to handle code transpiling and packaging. Being a fan of Vite, I asked once again if we could swap out Webpack for Vite. The new response provided me with the steps needed to create a simple Hello World extension using React, TypeScript, and Vite. These steps walked me through creating a new project based on a Vite template along with instructions to create or update existing files needed to build the extension. It even explained how to run the project locally. My final ask was to add support for TailwindCSS to the project for styling. 

After a quick conversation with Tabnine Chat, I had a simple but working Chrome extension to use as a starting point for my password generator. All this was accomplished in a fraction of the time it would take to research the old way.

Adding features incrementally

With a working base extension, it was time to add the necessary features for the password generator, one by one. The first task was to update the App component with a simple random password generator. With the App.tsx file open, I asked the chat to “update the App component to include a strong random password generator feature.” The response was an updated version of the App component that included a generate button that would populate a text input with a random password when clicked. The function to generate a strong password was also included. It styled everything using TailwindCSS without needing to be asked thanks to workspace context.

This was a decent start, but there was room for improvement. For starters, a copy button would be a nice addition. This was easy to add by highlighting the component and asking the chat to “add a copy button next to the password input field,” and then accepting the code suggestion.

In a similar fashion, I asked the chat to prefill a random password when the extension is opened and had it resize the header text. The next feature I wanted to add was a password strength indicator. I did this by asking the chat to “Add a password strength indicator that checks the password strength.” The response provided all the changes that need to be made to the App component including the function to calculate the password strength. I followed up with requests to make the input editable and for the indicator to update while edits are made.

The last feature I wanted to add was the ability to customize the length and character set used to generate the password. I started by asking the chat to “add a feature that allows the user to set a custom password length” and implementing that. Then I asked it to “add a feature that allows the user to customize the password character set, including numbers, special characters, and uppercase letters.” Once the code was updated, I made some minor changes to styling and event behavior.

This left me with a pretty good MVP version in a short amount of time.

Refactoring the code

Many times while building out the extension I found myself wanting to refactor the code. It’s very easy to keep adding new code to the App.tsx file, but it’s not a best practice. With a React project such as this, we usually want to break large components down into smaller ones stored in their own files and keep function logic separate. This not only helps reduce complexity but also aids with unit testing.

I was able to accomplish the refactoring by selecting the App component and asking the chat to pull different functionality into their own components. For example, the password generator became its own component that used a password strength indicator component. I also took the opportunity to dig deeper into the algorithms being used to generate and determine the password strength by having the chat explain them. This allowed me to see if anything could be simplified or improved by asking follow-up questions. 

Testing

Like so many developers, I saved testing for last. Using the chat, I set up my project to Vitest and the React Testing Library to handle unit testing. From there, I used Tabnine’s Testing Agent to generate unit tests for the different components and functions.

You do have to do some refining at the beginning to get the tests running. But once you do, the Testing Agent does a good job of suggesting tests needed to get you to full coverage. It’s definitely faster than doing it by hand.

After two hours of programming, I walked away with a Chrome extension that was probably 80-90% complete. Sure, it needs some design help and a few more unit tests, but it worked. I was able to take my existing web development knowledge and a little help from Tabnine to create something I’ve never attempted before. (And it was fun!)

Been holding back on building something due to a lack of know-how? Give it a try with Tabnine. Not already a Tabnine Pro user? Go sign up for a free 90-day trial.