Senior Software Engineer @ Abbove in Brussels, Belgium



To apply for this job please visit

Abbove is a leading wealth planning technology platform that aims to radically transform the way families relate to their wealth and interact with their trusted advisors.

Abbove’s platform empowers more than 1.000 wealth advisors to provide over 30.000 families across Europe with a new experience of wealth management that goes far beyond money. Abbove is transforming the private banking and wealth management industry, it is growing fast and it needs you to build up a sustainable future.

Your mission as a Senior Software Engineer

We are looking for a Senior Full-Stack Software Engineer or Engineering Manager. The ideal candidate will have proven experience in building scalable, high-quality, and high-performing web applications. Management experience is a plus.

Key responsibilities:

  • Design, develop, and maintain efficient, reusable, and reliable code.
  • Proven track record in writing automated tests.
  • Experience with legacy code.
  • Lead the full software development life cycle, from conception to deployment.
  • Ensure the performance, quality, and responsiveness of applications.
  • Collaborate with a team of engineers, designers, product managers.
  • Conduct code reviews, mentor junior developers, and enforce coding standards.
  • Keep abreast of new trends and best practices in web development.

Required skills and expertise

  • Bachelor’s/Master’s degree in Computer Science Engineering or similar experience.
  • Minimum of 5 years of experience in full-stack development.
  • Strong understanding of backend, front-end and datastores.
  • Proven experience in software development methodologies and best practices.
  • Excellent problem-solving skills and ability to work under tight deadlines.
  • Strong communication skills.

Preferred skills

  • Extensive experience with Ruby on Rails.
  • Experience with a frontend framework such as Turbo + Hotwire/Vue (or similar).
  • Leadership skills ideally as a manager.
  • Healthy appetite (and experience) to put on multiple engineering hats and help out on Docker/Terraform/AWS/CICD/ETL/…

Working in a scale up environment requires a high-level of professionalism, proactivity and autonomy. We work as a team and everyone can rely on other’s work. If you want to better understand our work environment and culture, have a look a our culture book.

What we offer

  • A full-time position with responsibility in which there’s room for your own creativity and initiatives.
  • The opportunity to grow with the company and to develop your role accordingly over time.
  • The chance to join a small, young, and talented team that’s not afraid of a bit of fun.
  • An attractive salary package.
  • An energetic, social, and flexible environment with the opportunity to work at our office in Brussels combined with some days of home working

By clicking “Accept All Cookies”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.
Privacy Preference Center
When you visit websites, they may store or retrieve data in your browser. This storage is often necessary for the basic functionality of the website. The storage may be used for marketing, analytics, and personalization of the site, such as storing your preferences. Privacy is important to us, so you have the option of disabling certain types of storage that may not be necessary for the basic functioning of the website. Blocking categories may impact your experience on the website.
Manage Consent Preferences by Category
Always Active
These items are required to enable basic website functionality.

These items are used to deliver advertising that is more relevant to you and your interests. They may also be used to limit the number of times you see an advertisement and measure the effectiveness of advertising campaigns. Advertising networks usually place them with the website operator’s permission.

These items allow the website to remember choices you make (such as your user name, language, or the region you are in) and provide enhanced, more personal features. For example, a website may provide you with local weather reports or traffic news by storing data about your current location.

These items help the website operator understand how its website performs, how visitors interact with the site, and whether there may be technical issues. This storage type usually doesn’t collect information that identifies a visitor.
/* smooth scrolling on iOS devices */ .fs-cc-prefs_content{-webkit-overflow-scrolling: touch}

// init Weglot Weglot.initialize({ api_key: ‘wg_e8abf9f6bbb7fdf3c6b7269a439ae7e03’ }); // on Weglot init Weglot.on(‘initialized’, ()=>{ // get the current active language const currentLang = Weglot.getCurrentLang(); // call updateDropdownLinks function updateSW5DropdownLinks(currentLang); }); // for each of the .wg-element-wrapper language links document.querySelectorAll(‘.wg-element-wrapper.sw5 [lang]’).forEach((link)=>{ // add a click event listener link.addEventListener(‘click’, function(e){ // prevent default e.preventDefault(); // switch to the current active language Weglot.switchTo(this.getAttribute(‘lang’)); // call updateDropdownLinks function updateSW5DropdownLinks(this.getAttribute(‘lang’)); }); }); // updateDropdownLinks function function updateSW5DropdownLinks(currentLang){ // get the wrapper element const $wrapper = document.querySelector(‘.wg-element-wrapper.sw5’); // if the .w-dropdown-toggle is not the current active language if($wrapper.querySelector(‘.w-dropdown-toggle’).getAttribute(‘lang’) !== currentLang){ // get the current active language link const $activeLangLink = $wrapper.querySelector(‘[lang=’+currentLang+’]’); // swap the dropdown toggle’s text with the current active language link text const $toggle = $activeLangLink.closest(‘.wg-element-wrapper’).querySelector(‘.w-dropdown-toggle’); const toggleTxt = $toggle.textContent; const activeLangLinkTxt = $activeLangLink.textContent; $toggle.querySelector(‘div’).textContent = activeLangLinkTxt; $activeLangLink.textContent = toggleTxt; // swap the dropdown toggle’s lang attr with the current active language link lang attr const lang = $activeLangLink.getAttribute(‘lang’); const toggleLang = $toggle.getAttribute(‘lang’); $toggle.setAttribute(‘lang’, lang); $activeLangLink.setAttribute(‘lang’, toggleLang); } } function getAllUrlParams(url) { // get query string from url (optional) or window var queryString = url ? url.split(‘?’)[1] :; // we’ll store the parameters here var obj = {}; // if query string exists if (queryString) { // stuff after # is not part of query string, so get rid of it queryString = queryString.split(‘#’)[0]; // split our query string into its component parts var arr = queryString.split(‘&’); for (var i = 0; i < arr.length; i++) { // separate the keys and the values var a = arr[i].split('='); // set parameter name and value (use 'true' if empty) var paramName = a[0]; var paramValue = typeof (a[1]) === 'undefined' ? true : a[1]; // (optional) keep case consistent paramName = paramName.toLowerCase(); if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase(); // if the paramName ends with square brackets, e.g. colors[] or colors[2] if (paramName.match(/[(d+)?]$/)) { // create key if it doesn't exist var key = paramName.replace(/[(d+)?]/, ''); if (!obj[key]) obj[key] = []; // if it's an indexed array e.g. colors[2] if (paramName.match(/[d+]$/)) { // get the index value and add the entry at the appropriate position var index = /[(d+)]/.exec(paramName)[1]; obj[key][index] = paramValue; } else { // otherwise add the value to the end of the array obj[key].push(paramValue); } } else { // we're dealing with a string if (!obj[paramName]) { // if it doesn't exist, create property obj[paramName] = paramValue; } else if (obj[paramName] && typeof obj[paramName] === 'string'){ // if property does exist and it's a string, convert it to an array obj[paramName] = [obj[paramName]]; obj[paramName].push(paramValue); } else { // otherwise add the property obj[paramName].push(paramValue); } } } } return obj; } /* get data object */ var getAllUrlParams = getAllUrlParams(); /* Check if the url with utm_parameters */ let isEmpty = jQuery.isEmptyObject(getAllUrlParams); if(!isEmpty){ /* utm data */ let utm_source_value = getAllUrlParams.utm_source; let utm_medium_value = getAllUrlParams.utm_medium; let utm_campaign_value = getAllUrlParams.utm_campaign; /* webflow form object (You should add embed code under webflow designer */ var utm_source_form_elem = document.getElementById("utm_source"); var utm_medium_form_elem = document.getElementById("utm_medium") var utm_campaign_form_elem = document.getElementById("utm_campaign"); /* Check if elem exsist to avoid console errors */ if(utm_source_form_elem){ utm_source_form_elem.value = utm_source_value; } if(utm_medium_form_elem){ utm_medium_form_elem.value = utm_medium_value; } if(utm_campaign_form_elem){ utm_campaign_form_elem.value = utm_campaign_value; } }