Author - sapu

We are Hiring a Product Marketing Consultant

UPDATE: This role has been filled so we are no longer accepting applicants. Thanks for your interest!

The TradeSkillMaster team is a small group of gamers who love to learn new skills and constantly push the boundaries of what TradeSkillMaster can do for our users. What started as a small addon has grown into a comprehensive gold making addon, desktop application, and set of web-based tools and resources. We are driven by self-improvement and creating a great set of products and services for our users, while working in an efficient, but low-stress environment.

We are always exploring new ways to improve the experience we offer to our users. To that end, we are looking for help in improving the various ways in which we communicate the value of our suite of tools to our users and potential users in the form of written content on our website and distribution platforms (Curseforge, Wago, etc), transactional emails, and more.

The Role

As a part of this role, you will be expected to work closely with other members of the team to create marketing content including copy and assets, ideate and manage marketing campaigns, and measure performance.

This position is short-term (3-6 months), part-time and paid. The work will be purely remote with NA/EU time zones strongly preferred.

About You


  • At least 3 years in roles with a significant focus on written digital marketing
  • Strong written communication skills
  • Experience with TradeSkillMaster and a passion for improving it

Ready to join us? Send me (Sapu) a message on Discord ( Come prepared with your resume, some examples of your past work, and any questions about the role you may have.

New Custom String Parsing


Custom strings have long been at the heart of what makes TradeSkillMaster such a versatile and powerful tool for gold making. They allow the user to focus on their gold making strategy, and allow the addon to worry about doing all the complex math for them. For example, the default Auctioning operation settings ensure that items will be posted above their vendor sell price and a percentage of an average of the crafting cost, realm market value, and region market value, while transparently accommodating items that can’t be either vendored or crafted, all without requiring the user to ever need to manually calculate or input those values. In v4.13, we completely rewrote how the addon parses and evaluates custom strings to allow for much greater optimization and user debuggability. This blog post will dive deep into the changes that were made and the performance improvements they’ve enabled.


TSM’s custom strings are defined by a set of functions and sources that can be used together in a single expression. As an example, let’s dissect the default Auctioning Operation minimum price setting:


There are a few things going on here. First of all, the outer check() function ensures that the first parameter is valid (and greater than 0); making the entire thing invalid if not. This is used here to ensure that the item has either a crafting cost, realm market value, or region market value. If all of these are missing for the item, we don’t have enough information available to properly post the item, so the custom string is made invalid to prevent posting the item at a potentially erroneous price. Assuming that check passes, we’re left with:


The max() function here takes the higher of its two parameters. The first parameter is the average of the crafting cost, realm market value, and region market value multiplied by 0.25. The second parameter is 1.5 times the vendor sell price. This ensures that this custom string always evaluates to at least 1.5 times the vendor sell price, even if the market values / crafting cost is very low. Both avg() and max() also have a side-effect of silently ignoring any invalid parameters, meaning if the item doesn’t have a crafting cost or a vendor sell price, the custom string can still be evaluated based on the other parameters.

Let’s plug some values into this custom string and see how it gets evaluated. Let’s assume we’re trying to post “Spice Bread” which has the following prices:

  • Crafting Cost: 35c
  • Vendor Sell Price: 5c
  • Market Value: 12s 70c
  • Region Market Value: 11s 57c

If we simply plug these into our custom string, we get the following:

	first(35c, 12s70c, 11s57c),
		0.25 * avg(35c, 12s70c, 11s57c),
		1.5 * 5c

After evaluating the first() and avg() functions:

	max(0.25 * 8s21c, 1.5 * 5c)

The first parameter of check() is valid (greater than 0) so it simply evaluates to its second parameter, the max(), which calculated out results in 2s5c.

This is the same math that TSM is doing under the hood, but obviously TSM needs to do it in a well-defined and programmatic manner. It has traditionally accomplished this by relying on the fact that the custom string syntax (that is, the format used to write custom strings) is very similar to valid Lua code (the programming language addons are written in), and Lua allows for dynamically loading and executing code. In other words, we can treat the custom string as Lua code and execute it directly as if it were programmed directly into the addon. However, we don’t simply want to directly execute what gets entered into a custom string setting for multiple reasons:

  1. We need to be able to plug in the correct value for the sources depending on the item which the custom string is being evaluated for.
  2. The set of functions which are valid in custom strings are specific to TSM, and not necessarily part of the Lua language itself.
  3. We need a way to ensure that what the user enters is a valid TSM custom string, and not just some arbitrary snippet of Lua code.

This was previously accomplished by doing a very rough tokenization of the string followed by applying some rules and string replacements to the tokens to ensure the input was valid and create a valid, loadable snippet of Lua code to present the custom string. Tokenization is the process of turning an arbitrary string (i.e. the entire custom string the user enters into a setting input) into a series of known words (a.k.a. tokens). For example, the custom string “max(crafting, vendorsell)” gets turned into the tokens:

  • max
  • (
  • crafting
  • ,
  • vendorsell
  • )

In this tokenized form, we can then easily perform a series of validation checks, such as requiring that there is an equal number of left and right parentheses, and replace sources and functions as appropriate to turn this into a valid snippet of Lua code we can execute:

function(helpers, _item)
	local result = helpers._max(
		helpers._priceHelper(_item, “crafting”),
		helpers._priceHelper(_item, “vendorsell”)
	if not result or helpers.IsInvalid(result) or result <= 0 then return end
	return result

Above is a simplified version of what the code generated by the original custom string implementation would look like. It looks very similar to the custom string we started with, but the sources have been replaced with function calls to look up the specified price for the item being evaluated, and the max() function call has been replaced with a call to a max() function TSM defines and provides.

This implementation has suited TSM well for a very long time, but has a few key limitations. First of all, the amount of validation that can be performed on a list of tokens is fairly limited and isn’t robust enough to catch all possible syntax errors. Having more robust processes in place for how custom strings are parsed will also enable better user-facing error messages and debugging functionality. Also, there’s no chance to perform any optimization on the generated code with this implementation. For example, if a custom string references the same source multiple times, the generated Lua code will look up the value of that source each and every time, with these lookups accounting for the majority of the computation time needed to evaluate custom strings in general.

New Implementation

The new implementation works much more like a traditional compiler and consists of 4 high-level steps: tokenization, abstract syntax tree generation, optimization, and code generation. We’ll use the following (somewhat contrived) custom string to demonstrate this process:
ifgt(crafting, 50g, crafting + 150% crafting, 10g + 5g)

For reference, here’s what that custom string would be converted to using the old system:

function(helpers, _item)
	local result = helpers._ifgt(
		helpers._priceHelper(_item, “crafting”),
		helpers._priceHelper(_item, “crafting”) +
			1.5 * helpers._priceHelper(_item, “crafting”),
		100000 + 50000,
	if not result or helpers.IsInvalid(result) or result <= 0 then return end
	return result


The tokenization step is similar to the prior implementation, but much more in-depth. It is responsible for taking the input string and converting it into a series of well-defined tokens which can then be more easily processed further. A token can be thought of similar to a word in an English sentence. It’s the smallest discrete unit which is meaningful by itself. The tokenizer works by methodically going through each character of the input string and separating out distinct tokens which are often separated by whitespace or formatting characters (i.e. parentheses or commas). In the case of our example (ignoring whitespace tokens), the tokenizer splits up our custom string into the following tokens:

ifgt ( crafting , 50g , crafting + 150 % crafting , 10g + 5g )

In addition to just splitting up the string into tokens, the tokenizer also classifies each token based on their type:

  • FUNCTION – ifgt
  • LEFT_PAREN – (
  • IDENTIFIER – crafting
  • COMMA – ,
  • MONEY – 50g
  • COMMA – ,
  • IDENTIFIER – crafting
  • NUMBER – 150
  • IDENTIFIER – crafting
  • COMMA – ,
  • MONEY – 10g
  • MONEY – 5g

The tokenization step takes care of a lot of the ambiguity of string parsing, and we now have a well-defined representation of the custom string which can more easily be worked with programmatically. The next step is to take this series of tokens and convert it into an abstract syntax tree, or AST for short.

AST Generation

An abstract syntax tree (AST) is a tree-based (per the name) form which better represents the structure of the custom string and the discrete operations (i.e. mathematical operations and / or function calls) which it consists of. A description of the algorithm for transforming the list of tokens into an AST is beyond the scope of this blog post, but we’ll visualize it with our example string, starting with a slightly more formatted version of the original string:

	crafting + 150 % crafting,
	10g + 5g

In this form, we can visually see that this example has an outer “ifgt” function which has 4 parameters. Its 3rd parameter consists of 2 separate math operations (“+” and “%”). The 4th parameter of the outer “ifgt” also consists of a “+” math operation. Each of these distinct functions and operations is turned into a node in the tree, with its arguments becoming its children:

This AST form is helpful for doing a few things:

  1. It abstracts away all the original syntax of the custom string with the order of operations entirely determined by the location of a node within the tree. For example, we can look at the tree and see that we must calculate the “%” operation of “150” and “crafting” before we can calculate the “+” operation, as the result of the former is a dependency of the latter.
  2. We can easily validate that functions are being used properly. The “ifgt” function can only take either 3 or 4 parameters. We can easily see from this tree form that the “ifgt” node in the tree has 4 direct children, and therefore the “ifgt” function has a valid number of arguments. One thing worth noting here is that TSM stores enough information in both this tree form and the token list in order to reverse the process back to the original string form. This allows TSM to point the user at exactly where their custom string is invalid, which is one of the main benefits of this new custom string implementation as a whole.
  3. Lastly, we can perform very well-informed optimizations based on this AST form, which we’ll dive into next.


Now that we have the custom string represented as an AST, we can methodically go through it and look for opportunities where we can optimize it without changing the result. There are dozens of different optimizations which are attempted at this stage, but for this example there are just a few which apply.

The first optimization we can perform here is to realize that taking “150%” of something is the same as multiplying it by 1.5. Multiplication is generally a lot easier to reason about than a “%” operator, so we’ll update that part of the tree accordingly:

If we zoom out one level from that new multiplication, we can see that we now have the expression “crafting + (1.5 * crafting)” which, using some simple rules of algebra, we can rewrite as “2.5 * crafting”, or in AST form as:

Lastly, we can see that the 4th argument of our “ifgt” function is simply adding two constant values together, which can be precomputed to just “15g” with our optimized AST looking like this:

Although this was a relatively contrived example, we were able to reduce the number of nodes in the AST from 11 down to just 7 just through some simple optimizations. Most importantly, we were able to get rid of one out of three of the “crafting” source nodes. These optimizations mean that TSM users can format their custom strings in a way which makes managing them as easy as possible rather than worrying about trying to write them in an optimal way. The addon itself will take care of all the optimization.

Code Generation

The last step is to turn our optimized AST into Lua code that can be executed by the addon. Compared to the previous custom string implementation, having the AST allows us to do this in a much more controlled and optimized way. For example, we can cache intermediate values so we only need to compute them a single time, even if they are used multiple times within the custom string. The generated code for our example custom string (edited for readability) is as follows:

return function(itemString, helpers)
	-- Locals
	local res_ifgt_1901082 = nil

	-- Code
	local var_crafting = helpers.GetPrice(itemString, "crafting")
	if var_crafting == helpers.INVALID then
		return nil

	if var_crafting > 500000 then
		res_ifgt_1901082 = (2.5 * var_crafting)
		res_ifgt_1901082 = 150000

	return helpers.ValidateResult(res_ifgt_1901082)

This code very closely matches our optimized AST, and has many optimizations when compared to our original custom string and the previous implementation. Most importantly, we only need to look up the “crafting” source for the item a single time, and then are able to reuse that multiple times within the generated code. One important optimization that’s not shown here is that we only evaluate sources as they are needed, and at most a single time. For example, if “crafting” was referenced in the “else” part of the “ifgt”, it would reference the same “var_crafting” variable rather than re-computing the crafting cost for the item.


Custom strings are one of the most powerful aspects of TSM, and we continue to dedicate significant time to improving their functionality and efficiency. With these under-the-hood improvements we made in 4.13, we are able to make the process of writing and debugging custom strings much better for all TSM users, while also improving their performance.

Dragonflight Update

In this post, we’re going to dive into where we’re at, what’s coming soon, and where we’re going with regards to supporting gold making in Dragonflight. I’ll start things off here by apologizing for not being as active as I would have liked with communicating this information sooner. TSM was definitely not as ready as I would have hoped for the changes in Dragonflight. There are a variety of reasons for this, which mainly boil down to not having enough development hours to spend and underestimating just how much of TSM would need to change to support the new profession changes. I understand people’s frustration with the state of TSM in Dragonflight so far, and am committed to improving things going forward. However, this will take some time.

Current State of Things

With that said, let’s talk about what changes we’ve made so far, and where things are at as of the time of writing (v4.12.20). The following things are working today:

  • For crafted commodity items, the crafting cost and profit will accurately display in the tooltip, and be available for use in custom strings (i.e. in Auctioning operation prices).
  • Quality, optional, and finishing materials can all be added manually to a recipe within the Crafting UI and then either crafted directly or added to the queue. Gathering then supports collecting all the materials as normal.
  • Restocking your groups based on Crafting operations is fully supported for crafted commodity items.

Coming Next

Here’s a list of things that are actively being worked on and can be expected to be released in the very near future:

  • Crafting cost and restocking support for quality crafts which produce gear of varying item levels.
  • Updated Destroying data for DF Milling, Prospecting, and Disenchanting.
  • Crafting UI support for selecting materials for and crafting recipes that don’t have fixed materials. This includes things like Mass Milling, Mass Prospecting, Recrafting, etc.
  • Improved UI for manually selected the target item for a quality craft, and having TSM automatically populate the cheapest set of quality materials needed.
  • Improved UI for selecting optional materials (including quality mats and finishing mats).
  • Display of crafting stats for quality crafts such as expected quality, inspiration, multicraft.
  • Support for taking inspiration into account when calculating the crafting cost.

Longer-Term Roadmap

There are a few other areas of TSM which definitely need some love and will be revisited in the not-too-distant future, which I thought I’d also call out here:

  • Improvements to how TSM handles buying commodities from the AH.
  • Item cache rebuilding performance improvements.
  • Account syncing performance improvements.

Crafting Cost

I thought it would be helpful to give some details on how we’re approaching crafting costs in Dragonflight. As we all know, Dragonflight greatly expanded the complexity of crafting things with professions. At its core, each recipe has a difficulty which gets matched up against your skill level to determine the result. That skill can then be modified with higher quality materials and various optional materials, as well as by proc’ing inspiration. In order to calculate how much it costs to craft something, TSM currently considers all the potential qualities of materials which result in the desired item being crafted.

As a hypothetical example, let’s assume there’s a potion which takes 1 herb and 1 vial to craft, with each of the materials being 1 of 3 qualities, and the recipe producing up to quality 3 of the potion. Let’s assume that using quality 3 of both materials results in quality 2 of the potion being crafted, and any other combination of materials results in quality 1 of the potion being crafted. To determine the crafting cost of the quality 1 potion, TSM will determine that there are 4 possible ways you could craft this item, from the 4 possible combinations of quality 1/2 of the herb, and quality 1/2 of the vial. TSM will then pick the cheapest of these options and use that as your crafting cost. Going further, it’s impossible to craft quality 3 of the potion, so TSM will treat that as an item you don’t yet know how to craft, and not display a crafting cost. Similarly, if you weren’t able to get your skill low enough to craft quality 1 of the potion anymore, TSM would treat that as something you can no longer craft and not show a crafting cost.

Currently, inspiration is not taken into account. From the above example, it’s possible that you could craft quality 3 of the potion if you were inspired. It seems like this will be important for some recipes where it won’t be feasible to get your skill high enough to craft at the highest quality without an inspiration proc for some crafts. This is something that’s not yet taken into account, but is something that we will plan to support in a future update as mentioned above.

Also, the game allows you to mix and max different qualities of the same material to hyper-optimize your crafting cost. For example, a recipe may require 5 of an herb, but you may only need to supply 1 at quality 3 with the remaining 4 being quality 1 in order to craft the desired quality of the crafted item. This isn’t something TSM takes into account, and is not something we have plans to support, due to the exponential increase in computing resource it would require to consider all possible permutations. Calculating crafting costs is already an order of magnitude slower than any other price source in TSM, so we felt that requiring all of a given material to be at the same quality struck the right balance between maximizing profits and keeping things performant and manageable for the user (i.e. when listing materials needed to craft something and/or gathering them).

Wrapping Up

In conclusion, there is a lot of work to do to get TSM where we want it to be for Dragonflight gold-making. This work is ongoing and we’re committed to aggressively work through the list of outstanding features and push out new functionality and bug fixes as they are ready. We’ll check in again with an update as things progress. If you have any feedback on the current state of things or the upcoming features, let us know in Discord.

New Public Web API

We are excited to announce that we are launching a brand new public web API! If you aren’t sure what this means, you can probably stop reading here and just keep an eye on for new spreadsheets and other out-of-game tools from our favorite content creators and other community members.


We launched the original version of our public API back in early 2016 to allow our users and 3rd party developers to integrate our pricing data in their spreadsheets and other out-of-game tools, websites, and programs. However, we took this version of our public API down at the beginning of Shadowlands as we worked behind the scenes on an extensive (and still ongoing) process of rebuilding all of the backend infrastructure and services which generate TSM pricing data and power our website and desktop application. As part of this, we’ve been working hard on bringing online a new version of our API which leverages this new infrastructure, and we’re finally ready to make it public.


The list of API endpoints we are releasing today covers all the same AuctionDB pricing data you would find in-game from realm-specific min buyout and market value, to region-wide sale prices and rates. This includes both base items and battle pets. This should enable a wide range out-of-game website and tools to leverage TSM’s data to build some great user experiences for gold-makers.

Get Started

Read through the documentation here to get started. We can’t wait to see what you build!

TSM Service Outage March 2022

Actions to Take

Let’s start with the actions you are recommended to take as a TSM user:

  • All users: Update the TSM Desktop Application to the latest version (r410)
    • Your app should update automatically, but you can download it here manually
  • All users: Re-select any Burning Crusade Realms previously configured on the Realm Selection Page for pricing data
  • All users: Enable any Group Notifications previously selected on the Deal Notifications Page


Early in the morning US time on Friday, March 25th, we were notified by our hosting provider that the hard drive containing our primary database died, and they were unable to recover any data from it. After a ton of work, we have since been able to restore all of our services. However, there was some data which we, unfortunately, were not able to recover, which is listed as follows:

  • Premium user addon backups
  • Desktop App realm selections for Burning Crusade realms
  • User configuration data for Group Notifications
  • Some other user account-level and user configuration changes between 4am PDT on March 24th and when our website was brought back online including new accounts and any other changes made on our website during that time

What we Did

We take regular backups of our database and quickly worked to restore from those backups on Friday. Unfortunately, we realized that our backup process had not been updated to include database tables related to Burning Crusade Classic. Additionally, a configuration issue with a script that manages Premium user addon backups also resulted in all backups being lost as a result of this outage.

On Saturday we brought the website back online in a read-only mode as we continued to try to restore some additional database data from a few raw database files which had not been corrupted. After much work, we were successful at restoring some additional data which we otherwise didn’t have proper backups of, but unfortunately, this still left us at the list above of completely lost data.

Naturally, the Premium user addon backups are the most critical. Working with a manifest of the missing files, we modified TSM Desktop Application (version r410) to re-upload any backup files that match the name from the recovered manifest. While we realize this does not guarantee a full recovery of all previously synced backups we have been able to get coverage of a majority of recent backups stored locally to Premium users.

With this in mind, we have set up a dedicated contact address that is available to Premium users who may be missing an important backup that was not captured in the re-upload efforts. We encourage those to reach out to [email protected] and we will explore any available options to make this right.

Additionally, with new resources available along with the protections and processes described in the next section of this post, we have removed the limit on the number of Premium user addon backups that can be marked as ‘saved’ and stored by TSM in the cloud going forward. This means Premium users no longer have to decide which backups to keep available long-term and all backups will be saved indefinitely.

Finally, if you created an account or reset your password on March 24th or March 25th and are having trouble logging in, it is recommended to re-create your account or reset your password again.

Learnings / Improvements

We’ve only had one outage like this in the past, but this one is significantly more serious given the loss of user data. We do take seriously the impact of this event and are working hard to correct things in the short-term, as we discussed above, as well as make immediate changes to prevent this from happening again in the future.

First and foremost, we’ve enabled multiple additional levels of redundancy and protection around our Premium user addon backups. This will prevent them from being irreversibly lost in the future, along with providing a mechanism to quickly recover them if any issues arise. This will have a non-negligible impact on our infrastructure costs, as it is certainly a non-trivial amount of data, especially with the change we’re making to not limit the number of backups we store for people but is the right thing to do given the importance of this data.

Next, we have addressed the gap in our database backup process which resulted in some user configuration data being lost, so any similar event in the future will just be a matter of quickly restoring the backups we have. We’ve also built a number of additional tools to help us recover any lost data in the future, although, of course, we hope we’ll never need to use those.

Lastly, the affected database has been running since 2016. A lot has changed since then in the server infrastructure space, and we’ve been steadily working over the past year to reimplement and migrate our backend services and infrastructure to a more modern, scalable, and maintainable architecture. Most of this has been behind the scenes and is already supporting more user-facing things like Ledger and all of the AuctionDB data which is downloaded by the desktop app, but this outage has definitely raised the importance of moving more things over to this much better system as quickly as possible.

Closing Thoughts

To wrap things up, we’d like to sincerely apologize for the inconvenience caused by this downtime and for the loss of data that occurred. We are looking forward to doing better and further improving the software and services we provide moving forward, and appreciate your continued support and usage of TSM. If you would like to share any thoughts, questions, or feedback – please feel free to share them in the #discussion channel on our Discord server.

Anatomy of a TSM Release: Feature Selection

In this series, we are detailing what goes on behind the scenes to ship a new major TSM addon release. Specifically, we will be describing how version 4.12 of the addon is being built, from deciding what features will be included, to publicly releasing it. This first post will focus on how we decided what features will be in version 4.12 of the addon.

Selection Criteria

There is no end to the list of things we want to implement into TSM to make it the best gold making addon possible. We have curated a list of improvements we are considering on our public roadmap, so any discussion on what we prioritize for the next version starts by reviewing the list there. Our biggest constraint as a team (and, not to get philosophical, but in life as well) is time, but there are many factors we consider as we filter through this list. In no particular order, and with much less formality than they are described here, these include the following high-level points:

  • What portion of our user base would benefit from this feature? How much value will this feature bring to them? How much complexity would it add to the addon for new users or those who wouldn’t directly benefit from it?
  • Is this feature especially relevant to the current state of the game or the other projects being worked on within TSM (i.e. new pricing data functionality)?
  • What resources (design time, development time, dependencies on our web backend or desktop app, etc) are required to ship this feature?

Back when we were deciding what the focus of TSM 4.11 was going to be, we went through a ranking exercise to help us prioritize our list of high-level features we wanted to implement. This resulted in optional material support and custom themes being prioritized for 4.11, and also Gathering being called out as the next big feature to prioritize in 4.12. Therefore, when it came time to plan out 4.12, we went in with the idea of Gathering being the primary focus.

Digging Deeper

Once we’ve decided on the primary feature, in this case Gathering, the next step is to go one level deeper and figure out exactly what use-cases we want to better support. This is almost entirely influenced by feedback we’ve received around Gathering from our users over the years. The most challenging part of this is deciding what we are NOT going to do. Again, we are balancing how much of our time we want to spend on a given feature (and how long before we can release it) vs. how much value it will deliver to our users. For example, Gathering for multiple characters at the same time is not something we are going to be doing in 4.12 because it would require a ton of design and development effort to do it in a way which doesn’t add a ton of complexity that the user needs to manage. It would also provide relatively-low value when compared with the other features, such as supporting intermediate crafts from other professions. The result of this exercise is again reflected in our public roadmap under the “Prioritised Ideas” column. In the case of 4.12, it includes the following:

  • A bunch of general usability and UI improvements to the Task List and Gathering tab of the Crafting UI
  • Adding support for gathering from the bank in Classic
  • Support intermediate crafts on alts as a Gathering source
  • Improved connected realm support
  • Add a default “Farming” source which will track how many the player has acquired through a more manual means

This is a fairly ambitious set of features, but we are fairly confident in being able to tackle them within 4.12. Of course, things may change as we go along, and we may tweak this list as we go through the design and implementation process. However, this list is what we are currently working towards delivering. In addition to the major feature of Gathering, we also went through our overall backlog of feature requests and pulled out a few things which we thought would be easy to implement and/or especially timely to pull into 4.12. This includes things like persisting the “Show Ungrouped Items as” selection between sessions.

Next Steps

The next steps are split between design and development. On the design side, we are brainstorming what a better UI/UX for the task list and Gathering tab looks and feels like. On the development side, we are starting to implement some of the backend changes to support the new features, and knocking out other things which don’t have any dependencies on the new UI.

We are Hiring a JavaScript (React) Developer

UPDATE 3/28: This position has been filled so we are no longer taking applicants for it. Thanks for your interest!

The TradeSkillMaster team is a small group of gamers who love to learn new skills and constantly push the boundaries of what TradeSkillMaster can do for our users. What started as a small addon has grown into a comprehensive gold making addon, desktop application, and set of web-based tools and resources. We are driven by self-improvement and creating a great set of products and services for our users, while working in an efficient, but low-stress environment.

We are always exploring new ways to improve the experience we offer to our users. To that end, we are working on a new version of our desktop application and are looking to add a passionate JS developer to the team to get it across the finish line and shipped to our hundreds of thousands of users.

The Role

As a part of this role, you will be expected to work closely with other members of the team to implement new features, constantly improve the overall quality of the codebase, and drive the project towards initial release and beyond.

This position is part-time (we all have day jobs) and paid hourly. While we are looking for somebody to work on a specific project initially (our new desktop application), this position may be extended beyond that. The work will be purely remote with NA/EU time zones strongly preferred.

About You

Minimum Qualifications:

  • Strong technical background in JS (React preferred) and good code design sense with an emphasis on UI and data processing
  • A proven ability to work in established code bases as part of a team and self-motivation to constantly improve code quality and processes

Preferred Qualifications:

  • The tech stack for this project includes React, Redux. Electron, Socket.IO, Node.js, and Python (backend), so expertise with any or all of those
  • An eagerness to learn about new technologies and jump into different areas of our overall tech stack (from in-game addon to backend infrastructure) as needed
  • Experience with TradeSkillMaster and a passion for improving it

Ready to join us? Send me (Sapu) a message on Discord ( – if I’m AFK I’ll respond ASAP) or send me an email ([email protected]). Come prepared with your resume and any questions about the role you may have.

Ledger Release and Beta Invites

The Ledger section in TSM4 has been in it’s temporary TSM3 placeholder mode until now. We’ve done a lot of work on the section and are proud to share with you the progress we’ve made on the powerful new tool that became of Accounting. The three updated sections you will find in the new Ledger are Revenue, Expenses and Failed Auctions. You will find they feel similar to their TSM3 counterparts, but with the much better look of TSM4.


You’ll find that the Inventory viewer isn’t finished yet. We hope to bring it to you soon. Until we do, we hope that you explore the Ledger update, and let us know what you think.

Hopefully you are as excited about the changes we are making to the Ledger in TSM4 as we are. To give these changes in the hands of more goblins as soon as possible we are also sending out a massive new wave of TSM4 beta invites every day this week. If you’ll be one of the lucky goblins joining us in the TSM4 beta, you’ll receive an email from us at the address associated with your TradeSkillMaster account. In this email, you’ll also find a link to an article on our knowledge base that explains how to setup your TSM app to access the beta and how you can join the #beta channel on discord, which is the dedicated place for feedback and questions pertaining to the TSM4 beta.

If you’re not already signed up, go ahead and sign up for the TSM4 beta here. If you like what we do and would like some extra functionality, please consider becoming a TSM premium user. It includes priority access to all of our betas, including TSM4.

Come join our Discord now!

The /r/woweconomy & TSM Discord is growing every day. We’re both incredibly flattered by and proud of the fact that there are now over 23 thousand users. Whether you’re only there to check prices once in awhile, partake in every discussion eagerly, or anything in between, thank you!

If you’re not yet familiar, there are many reasons why you should make the effort. Firstly all TSM support happens in channels dedicated to this purpose. TSM3 question go in the #tradeskillmaster channel, and any issues specific to the TSM4 beta are handled in the #beta channel.

There’s various channels available in the general discussion section too. Here you can discuss your goldmaking methods, or share that neat snipe you just bought! Don’t be afraid to talk with others, try to pick the best channel, and enjoy being a part of this ever growing community!

If you’re only looking to be kept up to date on the latest important news, there is a #news channel for that specific purpose! Large TSM updates, important Blizzard news and particularly important TSM news gets shared in there to offer you a central place.

In short, The /r/woweconomy & TSM Discord is becoming ever larger. It’s got a little bit for everyone, and you too should be a part of it. If you’re still not entirely convinced, simply join and see what you think. There’s even more channels and ways to communicate than just what’s mentioned here!

TSM is Hiring a Part-Time Addon Developer

The TradeSkillMaster team is a small group of gamers who love to learn new skills and constantly push the boundaries of what TradeSkillMaster can do for our users. What started as a small addon has grown into a suite of powerful addons, a desktop application, and an extensive set of web-based tools and resources. We are driven by self-improvement and creating a great set of products and services for our users, while working in an efficient, but laid-back environment.

At TradeSkillMaster, we always strive to improve the products and services we offer. To that end, we are looking for a passionate addon developer to work on adding critical new functionality to our in-game addons which are used by hundreds of thousands of people.

The Role

As a part of this role, you will be expected to work closely with other members of the team to implement exciting new features, constantly improve the overall quality of our codebase, and improve the general stability of the addon.

This position is specifically for somebody who would be working on the TSM addon (TSM4) 25-30 hours a week. Therefore, the ideal candidate would be an independent contractor (potentially with other, smaller workloads), and not somebody with a full-time job. The work would be purely remote, and there are limited requirements on location, but roughly NA/EU timezones are preferred.

About You

Minimum Qualifications:

  • Strong technical background and code design sense with an emphasis on UI and data processing
  • A proven ability to work in established code bases as part of a team and self-motivation to constantly improve code quality and processes

Preferred Qualifications:

  • Lua and WoW addon experience is a plus
  • SQL experience
  • Object-orientated programming
  • Experience with TradeSkillMaster and a passion for improving it

Ready to join us? Send me (Sapu) a message on Discord ( – if I’m AFK I’ll respond ASAP) or send me an email ([email protected]). Come prepared with your resume and any questions about the role you may have.