Hi Clintre,
Thank you for the detailed information and code snippet!
This way I was able to further test your case and come to a solution for it.
In order for your use case to work properly you need to bind for DOMContentLoaded event of the ‘document’ like so:

document.addEventListener('DOMContentLoaded', () => {
  async function fetchData() {
    let response = await fetch('/server.php');
    if (response.status === 200) {
        let kbData = await response.json();
        window.Smart('#kanban', class {
            get properties() {
                return {
                    addNewButton: true,
                    collapsible: true,
                    dataSource: kbData.tasks,
                    editable: true,
                    taskActions: true,
                    taskDue: true,
                    taskProgress: true,
                    userList: true,
                    users: kbData.users,
                    columns: [
                        { label: 'To do', dataField: 'toDo' },
                        { label: 'In progress', dataField: 'inProgress' },
                        { label: 'Testing', dataField: 'testing' },
                        { label: 'Done', dataField: 'done', addNewButton: false }
        return kbData

Also the same result can be achieved if you move all your scripts in the <head> tag.
And I strongly recommend you to add the following code in your php script when encoding the data into json like so:

header('Content-Type: application/json');
echo json_encode($out);

Let me know if that works for you!
Please, do not hesitate to contact us if you have any additional questions.
Best regards,
Yavor Dashev
Smart UI Team