Google Jules Walkthrough

Last week, Google released the public beta for Jules. Instead of a co-pilot or code completion tool, Jules is an asynchronous coding assistant intended to parallelize tasks and increase code throughput.
In this article, we’ll showcase Jules and how it can fit into our development pipeline.
The codebase
For this, we’ll create a simple ExpressJS API service for basic mathematical operations. We’ll use Jules to develop new features, fix bugs, and update documentation.
The starter code contains endpoints to do the following:
/add
- given two numbers as parameters add the numbers/subtract
- given two numbers as parameters subtract the second parameter (b
) from the first parameter (a
)
Using Jules
Jules is setup and connected to our repository. The process was straightforward to connect a single repository or organization in Github.
New Features
Let's add two new endpoints and the appropriate tests using Jules:
/multiply
- Multiply two numbers/divide
- Divide the first parameter by the second parameter
The first step is to prompt a task. Jules will provide a plan that summarizes steps to perform the tasks. Each task step contains natural language descriptions.

Once we approve the plan, Jules will asynchronously run the task plan and display code changes implemented. During this phase, we can provide feedback on any issues that may arise and Jules will update accordingly.


Once complete, Jules will create a commit for review. Here we can review the commit message and the code changes before pushing to a branch.

Once the branch is pushed, we can create a pull request for final review to merge into our main branch. The commit history will contain contributions from Jules.

Bug Fixes
While Jules was creating the /multiply
and /divide
endpoints, I implemented a new endpoint for negating a number (i.e. /negate
) and the appropriate tests.
app.get("/negate", (req, res) => {
const a = parseFloat(req.query.a);
res.json({ result: a * -1 });
});
Initial implementation for /negate
describe("GET /negate", () => {
it("should negate a number", async () => {
// Test for negating a positive number
const res = await request(app).get("/negate?num_a=5");
expect(res.statusCode).toBe(200);
expect(res.body.result).toBe(-5);
// Test for negating a negative number
const res2 = await request(app).get("/negate?num_a=-1");
expect(res2.statusCode).toBe(200);
expect(res2.body.result).toBe(1);
});
it("should return 400 if parameter is missing", async () => {
const res = await request(app).get("/negate");
expect(res.statusCode).toBe(400);
expect(res.body.error).toBe("Parameter num_a must be a number.");
});
it("should return 400 if parameter is not a number", async () => {
const res = await request(app).get("/negate?num_a=foo");
expect(res.statusCode).toBe(400);
expect(res.body.error).toBe("Parameter num_a must be a number.");
});
});
Unit tests for /negate
Unfortunately, I forgot to add error handling to /negate
when the parameter is not a number. I already pushed my code and found that my tests are failing. Instead of fetching and updating the code myself let’s use Jules to update my code.

Again, Jules will provide a task plan. Before we approve the plan, let’s amend the fix to include updating the parameter names to be more descriptive across all the endpoints as well.


Finally we let Jules do what it does best!

Update Documentation
Seems like all my feature and bug fixes have been implemented and merged into my main branch but I forgot to update the documentation. No worries I'll have Jules create it for me!


Considerations
So far we demonstrated various ways that Jules can accelerate our development workflow. However, it's not a silver bullet and there are some things to consider when using Jules.
Clear and concise tasks
Considering prompt best practices, Jules performs well when prompts are clear, concise, and targeted.
Jules had issues performing the initial scaffolding to our empty repository. At the current state it seems Jules is better designed for changes to an existing code base.
Another minor inconvenience was that Jules will default to a new branch for every task. Once committed, Jules can’t rename or change the working branch.

As a result, when prompting, ensure to include workflow and any other implementation details. The more details we provide, the better Jules will perform tasks.
Task plans have a time limit
Every task plan will auto approve and execute after a time period. For more complex task plans that need review make sure to pause the task so Jules doesn’t execute jobs prematurely.
In the future we’d like a mechanism to configure more time or an explicit approval instead of tasks auto-approving themselves.
Jules stops at the commit level
Jules currently can’t create any pull requests for our repositories. We’d like to see Jules include features that can enact on the full implementation lifecycle to essentially being another developer on the team. As a result, the engineering team can focus on a final review and implementing complex or ambiguous tasks.
Conclusions
The final output and commit history of the codebase can be reviewed here.
Jules is still in the beta phase but for being a week old the engineering team at SZNS was impressed. In this demo we were able to use Jules to parallelize feature development and bug fixes in less time it took to write this blog post!
At SZNS Solutions we’re optimistic on utilizing and evaluating the best agentic tools to perform more quickly, efficiently, and effectively. We look forward to feature updates and continued usage of Jules in our development workflow!
References
To learn more about Jules visit their documentation!