Skipping straight to a framework allows you to start building more impressive-looking projects sooner rather than later. That being said - don't do it. What you gain in instant gratification is lost in a deeper understanding of what is happening under the hood. This is not unlike what happens to self-taught developers who lack a computer science background.
Control flow: Control flow statements, such as if-else statements and loops, are used to control the flow of execution in your code. Understanding how to use these statements is important for building logic into your applications.
Functions: Functions are blocks of code that can be reused throughout your application. Understanding how to define and call functions is crucial for writing modular and maintainable code.
Asynchronous programming: Asynchronous programming allows your application to perform multiple tasks at the same time. Understanding how to use callbacks, promises and async/await is crucial for creating responsive and efficient applications.
It is worth mentioning that the list is not exhaustive and there are a lot more concepts that are important to master, however these are a good starting point for a basic understanding of the language. Also important to keep in mind is that practice, experimenting, and learning by doing are key to mastering the language and being able to apply the concepts in real-world projects.